| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| 6 | |
| 7 #include "xfa/include/fxgraphics/fx_graphics.h" | |
| 8 | |
| 9 #include <memory> | |
| 10 | |
| 11 #include "xfa/src/fxgraphics/fx_path_generator.h" | |
| 12 #include "xfa/src/fxgraphics/pre.h" | |
| 13 | |
| 14 class CAGG_Graphics { | |
| 15 public: | |
| 16 CAGG_Graphics(); | |
| 17 FX_ERR Create(CFX_Graphics* owner, | |
| 18 int32_t width, | |
| 19 int32_t height, | |
| 20 FXDIB_Format format); | |
| 21 virtual ~CAGG_Graphics(); | |
| 22 | |
| 23 private: | |
| 24 CFX_Graphics* _owner; | |
| 25 }; | |
| 26 CFX_Graphics::CFX_Graphics() { | |
| 27 _type = FX_CONTEXT_None; | |
| 28 _info._graphState.SetDashCount(0); | |
| 29 _info._isAntialiasing = TRUE; | |
| 30 _info._strokeAlignment = FX_STROKEALIGNMENT_Center; | |
| 31 _info._CTM.SetIdentity(); | |
| 32 _info._isActOnDash = FALSE; | |
| 33 _info._strokeColor = NULL; | |
| 34 _info._fillColor = NULL; | |
| 35 _info._font = NULL; | |
| 36 _info._fontSize = 40.0; | |
| 37 _info._fontHScale = 1.0; | |
| 38 _info._fontSpacing = 0.0; | |
| 39 _renderDevice = NULL; | |
| 40 _aggGraphics = NULL; | |
| 41 } | |
| 42 FX_ERR CFX_Graphics::Create(CFX_RenderDevice* renderDevice, | |
| 43 FX_BOOL isAntialiasing) { | |
| 44 if (!renderDevice) | |
| 45 return FX_ERR_Parameter_Invalid; | |
| 46 if (_type != FX_CONTEXT_None) { | |
| 47 return FX_ERR_Property_Invalid; | |
| 48 } | |
| 49 _type = FX_CONTEXT_Device; | |
| 50 _info._isAntialiasing = isAntialiasing; | |
| 51 _renderDevice = renderDevice; | |
| 52 if (_renderDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP) { | |
| 53 return FX_ERR_Succeeded; | |
| 54 } | |
| 55 return FX_ERR_Indefinite; | |
| 56 } | |
| 57 FX_ERR CFX_Graphics::Create(int32_t width, | |
| 58 int32_t height, | |
| 59 FXDIB_Format format, | |
| 60 FX_BOOL isNative, | |
| 61 FX_BOOL isAntialiasing) { | |
| 62 if (_type != FX_CONTEXT_None) { | |
| 63 return FX_ERR_Property_Invalid; | |
| 64 } | |
| 65 _type = FX_CONTEXT_Device; | |
| 66 _info._isAntialiasing = isAntialiasing; | |
| 67 { | |
| 68 _aggGraphics = new CAGG_Graphics; | |
| 69 return _aggGraphics->Create(this, width, height, format); | |
| 70 } | |
| 71 } | |
| 72 CFX_Graphics::~CFX_Graphics() { | |
| 73 if (_aggGraphics) { | |
| 74 delete _aggGraphics; | |
| 75 _aggGraphics = NULL; | |
| 76 } | |
| 77 _renderDevice = NULL; | |
| 78 _info._graphState.SetDashCount(0); | |
| 79 _type = FX_CONTEXT_None; | |
| 80 } | |
| 81 FX_ERR CFX_Graphics::GetDeviceCap(const int32_t capID, FX_DeviceCap& capVal) { | |
| 82 switch (_type) { | |
| 83 case FX_CONTEXT_Device: { | |
| 84 if (!_renderDevice) | |
| 85 return FX_ERR_Property_Invalid; | |
| 86 capVal = _renderDevice->GetDeviceCaps(capID); | |
| 87 return FX_ERR_Succeeded; | |
| 88 } | |
| 89 default: { return FX_ERR_Property_Invalid; } | |
| 90 } | |
| 91 } | |
| 92 FX_ERR CFX_Graphics::IsPrinterDevice(FX_BOOL& isPrinter) { | |
| 93 switch (_type) { | |
| 94 case FX_CONTEXT_Device: { | |
| 95 if (!_renderDevice) | |
| 96 return FX_ERR_Property_Invalid; | |
| 97 int32_t deviceClass = _renderDevice->GetDeviceClass(); | |
| 98 if (deviceClass == FXDC_PRINTER) { | |
| 99 isPrinter = TRUE; | |
| 100 } else { | |
| 101 isPrinter = FALSE; | |
| 102 } | |
| 103 return FX_ERR_Succeeded; | |
| 104 } | |
| 105 default: { return FX_ERR_Property_Invalid; } | |
| 106 } | |
| 107 } | |
| 108 FX_ERR CFX_Graphics::EnableAntialiasing(FX_BOOL isAntialiasing) { | |
| 109 switch (_type) { | |
| 110 case FX_CONTEXT_Device: { | |
| 111 if (!_renderDevice) | |
| 112 return FX_ERR_Property_Invalid; | |
| 113 _info._isAntialiasing = isAntialiasing; | |
| 114 return FX_ERR_Succeeded; | |
| 115 } | |
| 116 default: { return FX_ERR_Property_Invalid; } | |
| 117 } | |
| 118 } | |
| 119 FX_ERR CFX_Graphics::SaveGraphState() { | |
| 120 switch (_type) { | |
| 121 case FX_CONTEXT_Device: { | |
| 122 if (!_renderDevice) | |
| 123 return FX_ERR_Property_Invalid; | |
| 124 _renderDevice->SaveState(); | |
| 125 TInfo* info = new TInfo; | |
| 126 info->_graphState.Copy(_info._graphState); | |
| 127 info->_isAntialiasing = _info._isAntialiasing; | |
| 128 info->_strokeAlignment = _info._strokeAlignment; | |
| 129 info->_CTM = _info._CTM; | |
| 130 info->_isActOnDash = _info._isActOnDash; | |
| 131 info->_strokeColor = _info._strokeColor; | |
| 132 info->_fillColor = _info._fillColor; | |
| 133 info->_font = _info._font; | |
| 134 info->_fontSize = _info._fontSize; | |
| 135 info->_fontHScale = _info._fontHScale; | |
| 136 info->_fontSpacing = _info._fontSpacing; | |
| 137 _infoStack.Add(info); | |
| 138 return FX_ERR_Succeeded; | |
| 139 } | |
| 140 default: { return FX_ERR_Property_Invalid; } | |
| 141 } | |
| 142 } | |
| 143 FX_ERR CFX_Graphics::RestoreGraphState() { | |
| 144 switch (_type) { | |
| 145 case FX_CONTEXT_Device: { | |
| 146 if (!_renderDevice) | |
| 147 return FX_ERR_Property_Invalid; | |
| 148 _renderDevice->RestoreState(); | |
| 149 int32_t size = _infoStack.GetSize(); | |
| 150 if (size <= 0) { | |
| 151 return FX_ERR_Intermediate_Value_Invalid; | |
| 152 } | |
| 153 int32_t topIndex = size - 1; | |
| 154 TInfo* info = (TInfo*)_infoStack.GetAt(topIndex); | |
| 155 if (!info) | |
| 156 return FX_ERR_Intermediate_Value_Invalid; | |
| 157 _info._graphState.Copy(info->_graphState); | |
| 158 _info._isAntialiasing = info->_isAntialiasing; | |
| 159 _info._strokeAlignment = info->_strokeAlignment; | |
| 160 _info._CTM = info->_CTM; | |
| 161 _info._isActOnDash = info->_isActOnDash; | |
| 162 _info._strokeColor = info->_strokeColor; | |
| 163 _info._fillColor = info->_fillColor; | |
| 164 _info._font = info->_font; | |
| 165 _info._fontSize = info->_fontSize; | |
| 166 _info._fontHScale = info->_fontHScale; | |
| 167 _info._fontSpacing = info->_fontSpacing; | |
| 168 delete info; | |
| 169 info = NULL; | |
| 170 _infoStack.RemoveAt(topIndex); | |
| 171 return FX_ERR_Succeeded; | |
| 172 } | |
| 173 default: { return FX_ERR_Property_Invalid; } | |
| 174 } | |
| 175 } | |
| 176 FX_ERR CFX_Graphics::GetLineCap(CFX_GraphStateData::LineCap& lineCap) { | |
| 177 switch (_type) { | |
| 178 case FX_CONTEXT_Device: { | |
| 179 if (!_renderDevice) | |
| 180 return FX_ERR_Property_Invalid; | |
| 181 lineCap = _info._graphState.m_LineCap; | |
| 182 return FX_ERR_Succeeded; | |
| 183 } | |
| 184 default: { return FX_ERR_Property_Invalid; } | |
| 185 } | |
| 186 } | |
| 187 FX_ERR CFX_Graphics::SetLineCap(CFX_GraphStateData::LineCap lineCap) { | |
| 188 switch (_type) { | |
| 189 case FX_CONTEXT_Device: { | |
| 190 if (!_renderDevice) | |
| 191 return FX_ERR_Property_Invalid; | |
| 192 _info._graphState.m_LineCap = lineCap; | |
| 193 return FX_ERR_Succeeded; | |
| 194 } | |
| 195 default: { return FX_ERR_Property_Invalid; } | |
| 196 } | |
| 197 } | |
| 198 FX_ERR CFX_Graphics::GetDashCount(int32_t& dashCount) { | |
| 199 switch (_type) { | |
| 200 case FX_CONTEXT_Device: { | |
| 201 if (!_renderDevice) | |
| 202 return FX_ERR_Property_Invalid; | |
| 203 dashCount = _info._graphState.m_DashCount; | |
| 204 return FX_ERR_Succeeded; | |
| 205 } | |
| 206 default: { return FX_ERR_Property_Invalid; } | |
| 207 } | |
| 208 } | |
| 209 FX_ERR CFX_Graphics::GetLineDash(FX_FLOAT& dashPhase, FX_FLOAT* dashArray) { | |
| 210 if (!dashArray) | |
| 211 return FX_ERR_Parameter_Invalid; | |
| 212 switch (_type) { | |
| 213 case FX_CONTEXT_Device: { | |
| 214 if (!_renderDevice) | |
| 215 return FX_ERR_Property_Invalid; | |
| 216 dashPhase = _info._graphState.m_DashPhase; | |
| 217 FXSYS_memcpy(dashArray, _info._graphState.m_DashArray, | |
| 218 _info._graphState.m_DashCount * sizeof(FX_FLOAT)); | |
| 219 return FX_ERR_Succeeded; | |
| 220 } | |
| 221 default: { return FX_ERR_Property_Invalid; } | |
| 222 } | |
| 223 } | |
| 224 FX_ERR CFX_Graphics::SetLineDash(FX_FLOAT dashPhase, | |
| 225 FX_FLOAT* dashArray, | |
| 226 int32_t dashCount) { | |
| 227 if (dashCount > 0 && !dashArray) { | |
| 228 return FX_ERR_Parameter_Invalid; | |
| 229 } | |
| 230 dashCount = dashCount < 0 ? 0 : dashCount; | |
| 231 switch (_type) { | |
| 232 case FX_CONTEXT_Device: { | |
| 233 if (!_renderDevice) | |
| 234 return FX_ERR_Property_Invalid; | |
| 235 FX_FLOAT scale = 1.0; | |
| 236 if (_info._isActOnDash) { | |
| 237 scale = _info._graphState.m_LineWidth; | |
| 238 } | |
| 239 _info._graphState.m_DashPhase = dashPhase; | |
| 240 _info._graphState.SetDashCount(dashCount); | |
| 241 for (int32_t i = 0; i < dashCount; i++) { | |
| 242 _info._graphState.m_DashArray[i] = dashArray[i] * scale; | |
| 243 } | |
| 244 return FX_ERR_Succeeded; | |
| 245 } | |
| 246 default: { return FX_ERR_Property_Invalid; } | |
| 247 } | |
| 248 } | |
| 249 FX_ERR CFX_Graphics::SetLineDash(FX_DashStyle dashStyle) { | |
| 250 switch (_type) { | |
| 251 case FX_CONTEXT_Device: { | |
| 252 if (!_renderDevice) | |
| 253 return FX_ERR_Property_Invalid; | |
| 254 return RenderDeviceSetLineDash(dashStyle); | |
| 255 } | |
| 256 default: { return FX_ERR_Property_Invalid; } | |
| 257 } | |
| 258 } | |
| 259 FX_ERR CFX_Graphics::GetLineJoin(CFX_GraphStateData::LineJoin& lineJoin) { | |
| 260 switch (_type) { | |
| 261 case FX_CONTEXT_Device: { | |
| 262 if (!_renderDevice) | |
| 263 return FX_ERR_Property_Invalid; | |
| 264 lineJoin = _info._graphState.m_LineJoin; | |
| 265 return FX_ERR_Succeeded; | |
| 266 } | |
| 267 default: { return FX_ERR_Property_Invalid; } | |
| 268 } | |
| 269 } | |
| 270 FX_ERR CFX_Graphics::SetLineJoin(CFX_GraphStateData::LineJoin lineJoin) { | |
| 271 switch (_type) { | |
| 272 case FX_CONTEXT_Device: { | |
| 273 if (!_renderDevice) | |
| 274 return FX_ERR_Property_Invalid; | |
| 275 _info._graphState.m_LineJoin = lineJoin; | |
| 276 return FX_ERR_Succeeded; | |
| 277 } | |
| 278 default: { return FX_ERR_Property_Invalid; } | |
| 279 } | |
| 280 } | |
| 281 FX_ERR CFX_Graphics::GetMiterLimit(FX_FLOAT& miterLimit) { | |
| 282 switch (_type) { | |
| 283 case FX_CONTEXT_Device: { | |
| 284 if (!_renderDevice) | |
| 285 return FX_ERR_Property_Invalid; | |
| 286 miterLimit = _info._graphState.m_MiterLimit; | |
| 287 return FX_ERR_Succeeded; | |
| 288 } | |
| 289 default: { return FX_ERR_Property_Invalid; } | |
| 290 } | |
| 291 } | |
| 292 FX_ERR CFX_Graphics::SetMiterLimit(FX_FLOAT miterLimit) { | |
| 293 switch (_type) { | |
| 294 case FX_CONTEXT_Device: { | |
| 295 if (!_renderDevice) | |
| 296 return FX_ERR_Property_Invalid; | |
| 297 _info._graphState.m_MiterLimit = miterLimit; | |
| 298 return FX_ERR_Succeeded; | |
| 299 } | |
| 300 default: { return FX_ERR_Property_Invalid; } | |
| 301 } | |
| 302 } | |
| 303 FX_ERR CFX_Graphics::GetLineWidth(FX_FLOAT& lineWidth) { | |
| 304 switch (_type) { | |
| 305 case FX_CONTEXT_Device: { | |
| 306 if (!_renderDevice) | |
| 307 return FX_ERR_Property_Invalid; | |
| 308 lineWidth = _info._graphState.m_LineWidth; | |
| 309 return FX_ERR_Succeeded; | |
| 310 } | |
| 311 default: { return FX_ERR_Property_Invalid; } | |
| 312 } | |
| 313 } | |
| 314 FX_ERR CFX_Graphics::SetLineWidth(FX_FLOAT lineWidth, FX_BOOL isActOnDash) { | |
| 315 switch (_type) { | |
| 316 case FX_CONTEXT_Device: { | |
| 317 if (!_renderDevice) | |
| 318 return FX_ERR_Property_Invalid; | |
| 319 _info._graphState.m_LineWidth = lineWidth; | |
| 320 _info._isActOnDash = isActOnDash; | |
| 321 return FX_ERR_Succeeded; | |
| 322 } | |
| 323 default: { return FX_ERR_Property_Invalid; } | |
| 324 } | |
| 325 } | |
| 326 FX_ERR CFX_Graphics::GetStrokeAlignment(FX_StrokeAlignment& strokeAlignment) { | |
| 327 switch (_type) { | |
| 328 case FX_CONTEXT_Device: { | |
| 329 if (!_renderDevice) | |
| 330 return FX_ERR_Property_Invalid; | |
| 331 strokeAlignment = _info._strokeAlignment; | |
| 332 return FX_ERR_Succeeded; | |
| 333 } | |
| 334 default: { return FX_ERR_Property_Invalid; } | |
| 335 } | |
| 336 } | |
| 337 FX_ERR CFX_Graphics::SetStrokeAlignment(FX_StrokeAlignment strokeAlignment) { | |
| 338 switch (_type) { | |
| 339 case FX_CONTEXT_Device: { | |
| 340 if (!_renderDevice) | |
| 341 return FX_ERR_Property_Invalid; | |
| 342 _info._strokeAlignment = strokeAlignment; | |
| 343 return FX_ERR_Succeeded; | |
| 344 } | |
| 345 default: { return FX_ERR_Property_Invalid; } | |
| 346 } | |
| 347 } | |
| 348 FX_ERR CFX_Graphics::SetStrokeColor(CFX_Color* color) { | |
| 349 if (!color) | |
| 350 return FX_ERR_Parameter_Invalid; | |
| 351 switch (_type) { | |
| 352 case FX_CONTEXT_Device: { | |
| 353 if (!_renderDevice) | |
| 354 return FX_ERR_Property_Invalid; | |
| 355 _info._strokeColor = color; | |
| 356 return FX_ERR_Succeeded; | |
| 357 } | |
| 358 default: { return FX_ERR_Property_Invalid; } | |
| 359 } | |
| 360 } | |
| 361 FX_ERR CFX_Graphics::SetFillColor(CFX_Color* color) { | |
| 362 if (!color) | |
| 363 return FX_ERR_Parameter_Invalid; | |
| 364 switch (_type) { | |
| 365 case FX_CONTEXT_Device: { | |
| 366 if (!_renderDevice) | |
| 367 return FX_ERR_Property_Invalid; | |
| 368 _info._fillColor = color; | |
| 369 return FX_ERR_Succeeded; | |
| 370 } | |
| 371 default: { return FX_ERR_Property_Invalid; } | |
| 372 } | |
| 373 } | |
| 374 FX_ERR CFX_Graphics::StrokePath(CFX_Path* path, CFX_Matrix* matrix) { | |
| 375 if (!path) | |
| 376 return FX_ERR_Parameter_Invalid; | |
| 377 switch (_type) { | |
| 378 case FX_CONTEXT_Device: { | |
| 379 if (!_renderDevice) | |
| 380 return FX_ERR_Property_Invalid; | |
| 381 return RenderDeviceStrokePath(path, matrix); | |
| 382 } | |
| 383 default: { return FX_ERR_Property_Invalid; } | |
| 384 } | |
| 385 } | |
| 386 FX_ERR CFX_Graphics::FillPath(CFX_Path* path, | |
| 387 FX_FillMode fillMode, | |
| 388 CFX_Matrix* matrix) { | |
| 389 if (!path) | |
| 390 return FX_ERR_Parameter_Invalid; | |
| 391 switch (_type) { | |
| 392 case FX_CONTEXT_Device: { | |
| 393 if (!_renderDevice) | |
| 394 return FX_ERR_Property_Invalid; | |
| 395 return RenderDeviceFillPath(path, fillMode, matrix); | |
| 396 } | |
| 397 default: { return FX_ERR_Property_Invalid; } | |
| 398 } | |
| 399 } | |
| 400 FX_ERR CFX_Graphics::ClipPath(CFX_Path* path, | |
| 401 FX_FillMode fillMode, | |
| 402 CFX_Matrix* matrix) { | |
| 403 if (!path) | |
| 404 return FX_ERR_Parameter_Invalid; | |
| 405 switch (_type) { | |
| 406 case FX_CONTEXT_Device: { | |
| 407 if (!_renderDevice) | |
| 408 return FX_ERR_Property_Invalid; | |
| 409 FX_BOOL result = _renderDevice->SetClip_PathFill( | |
| 410 path->GetPathData(), (CFX_Matrix*)matrix, fillMode); | |
| 411 if (!result) | |
| 412 return FX_ERR_Indefinite; | |
| 413 return FX_ERR_Succeeded; | |
| 414 } | |
| 415 default: { return FX_ERR_Property_Invalid; } | |
| 416 } | |
| 417 } | |
| 418 FX_ERR CFX_Graphics::DrawImage(CFX_DIBSource* source, | |
| 419 const CFX_PointF& point, | |
| 420 CFX_Matrix* matrix) { | |
| 421 if (!source) | |
| 422 return FX_ERR_Parameter_Invalid; | |
| 423 switch (_type) { | |
| 424 case FX_CONTEXT_Device: { | |
| 425 if (!_renderDevice) | |
| 426 return FX_ERR_Property_Invalid; | |
| 427 return RenderDeviceDrawImage(source, point, matrix); | |
| 428 } | |
| 429 default: { return FX_ERR_Property_Invalid; } | |
| 430 } | |
| 431 } | |
| 432 FX_ERR CFX_Graphics::StretchImage(CFX_DIBSource* source, | |
| 433 const CFX_RectF& rect, | |
| 434 CFX_Matrix* matrix) { | |
| 435 if (!source) | |
| 436 return FX_ERR_Parameter_Invalid; | |
| 437 switch (_type) { | |
| 438 case FX_CONTEXT_Device: { | |
| 439 if (!_renderDevice) | |
| 440 return FX_ERR_Property_Invalid; | |
| 441 return RenderDeviceStretchImage(source, rect, matrix); | |
| 442 } | |
| 443 default: { return FX_ERR_Property_Invalid; } | |
| 444 } | |
| 445 } | |
| 446 FX_ERR CFX_Graphics::ConcatMatrix(const CFX_Matrix* matrix) { | |
| 447 if (!matrix) | |
| 448 return FX_ERR_Parameter_Invalid; | |
| 449 switch (_type) { | |
| 450 case FX_CONTEXT_Device: { | |
| 451 if (!_renderDevice) | |
| 452 return FX_ERR_Property_Invalid; | |
| 453 _info._CTM.Concat(*matrix); | |
| 454 return FX_ERR_Succeeded; | |
| 455 } | |
| 456 default: { return FX_ERR_Property_Invalid; } | |
| 457 } | |
| 458 } | |
| 459 CFX_Matrix* CFX_Graphics::GetMatrix() { | |
| 460 switch (_type) { | |
| 461 case FX_CONTEXT_Device: { | |
| 462 if (!_renderDevice) | |
| 463 return NULL; | |
| 464 return &_info._CTM; | |
| 465 } | |
| 466 default: { return NULL; } | |
| 467 } | |
| 468 } | |
| 469 FX_ERR CFX_Graphics::GetClipRect(CFX_RectF& rect) { | |
| 470 switch (_type) { | |
| 471 case FX_CONTEXT_Device: { | |
| 472 if (!_renderDevice) | |
| 473 return FX_ERR_Property_Invalid; | |
| 474 FX_RECT r = _renderDevice->GetClipBox(); | |
| 475 rect.left = (FX_FLOAT)r.left; | |
| 476 rect.top = (FX_FLOAT)r.top; | |
| 477 rect.width = (FX_FLOAT)r.Width(); | |
| 478 rect.height = (FX_FLOAT)r.Height(); | |
| 479 return FX_ERR_Succeeded; | |
| 480 } | |
| 481 default: { return FX_ERR_Property_Invalid; } | |
| 482 } | |
| 483 } | |
| 484 FX_ERR CFX_Graphics::SetClipRect(const CFX_RectF& rect) { | |
| 485 switch (_type) { | |
| 486 case FX_CONTEXT_Device: { | |
| 487 if (!_renderDevice) | |
| 488 return FX_ERR_Property_Invalid; | |
| 489 if (!_renderDevice->SetClip_Rect( | |
| 490 FX_RECT(FXSYS_round(rect.left), FXSYS_round(rect.top), | |
| 491 FXSYS_round(rect.right()), FXSYS_round(rect.bottom())))) { | |
| 492 return FX_ERR_Method_Not_Supported; | |
| 493 } | |
| 494 return FX_ERR_Succeeded; | |
| 495 } | |
| 496 default: { return FX_ERR_Property_Invalid; } | |
| 497 } | |
| 498 } | |
| 499 FX_ERR CFX_Graphics::ClearClip() { | |
| 500 switch (_type) { | |
| 501 case FX_CONTEXT_Device: { | |
| 502 if (!_renderDevice) | |
| 503 return FX_ERR_Property_Invalid; | |
| 504 return FX_ERR_Succeeded; | |
| 505 } | |
| 506 default: { return FX_ERR_Property_Invalid; } | |
| 507 } | |
| 508 } | |
| 509 FX_ERR CFX_Graphics::SetFont(CFX_Font* font) { | |
| 510 if (!font) | |
| 511 return FX_ERR_Parameter_Invalid; | |
| 512 switch (_type) { | |
| 513 case FX_CONTEXT_Device: { | |
| 514 if (!_renderDevice) | |
| 515 return FX_ERR_Property_Invalid; | |
| 516 _info._font = font; | |
| 517 return FX_ERR_Succeeded; | |
| 518 } | |
| 519 default: { return FX_ERR_Property_Invalid; } | |
| 520 } | |
| 521 } | |
| 522 FX_ERR CFX_Graphics::SetFontSize(const FX_FLOAT size) { | |
| 523 FX_FLOAT fontSize = size <= 0 ? 1.0f : size; | |
| 524 switch (_type) { | |
| 525 case FX_CONTEXT_Device: { | |
| 526 if (!_renderDevice) | |
| 527 return FX_ERR_Property_Invalid; | |
| 528 _info._fontSize = fontSize; | |
| 529 return FX_ERR_Succeeded; | |
| 530 } | |
| 531 default: { return FX_ERR_Property_Invalid; } | |
| 532 } | |
| 533 } | |
| 534 FX_ERR CFX_Graphics::SetFontHScale(const FX_FLOAT scale) { | |
| 535 FX_FLOAT fontHScale = scale <= 0 ? 1.0f : scale; | |
| 536 switch (_type) { | |
| 537 case FX_CONTEXT_Device: { | |
| 538 if (!_renderDevice) | |
| 539 return FX_ERR_Property_Invalid; | |
| 540 _info._fontHScale = fontHScale; | |
| 541 return FX_ERR_Succeeded; | |
| 542 } | |
| 543 default: { return FX_ERR_Property_Invalid; } | |
| 544 } | |
| 545 } | |
| 546 FX_ERR CFX_Graphics::SetCharSpacing(const FX_FLOAT spacing) { | |
| 547 FX_FLOAT fontSpacing = spacing < 0 ? 0 : spacing; | |
| 548 switch (_type) { | |
| 549 case FX_CONTEXT_Device: { | |
| 550 if (!_renderDevice) | |
| 551 return FX_ERR_Property_Invalid; | |
| 552 _info._fontSpacing = fontSpacing; | |
| 553 return FX_ERR_Succeeded; | |
| 554 } | |
| 555 default: { return FX_ERR_Property_Invalid; } | |
| 556 } | |
| 557 } | |
| 558 FX_ERR CFX_Graphics::SetTextDrawingMode(const int32_t mode) { | |
| 559 switch (_type) { | |
| 560 case FX_CONTEXT_Device: { | |
| 561 if (!_renderDevice) | |
| 562 return FX_ERR_Property_Invalid; | |
| 563 return FX_ERR_Succeeded; | |
| 564 } | |
| 565 default: { return FX_ERR_Property_Invalid; } | |
| 566 } | |
| 567 } | |
| 568 FX_ERR CFX_Graphics::ShowText(const CFX_PointF& point, | |
| 569 const CFX_WideString& text, | |
| 570 CFX_Matrix* matrix) { | |
| 571 switch (_type) { | |
| 572 case FX_CONTEXT_Device: { | |
| 573 if (!_renderDevice) | |
| 574 return FX_ERR_Property_Invalid; | |
| 575 return RenderDeviceShowText(point, text, matrix); | |
| 576 } | |
| 577 default: { return FX_ERR_Property_Invalid; } | |
| 578 } | |
| 579 } | |
| 580 FX_ERR CFX_Graphics::CalcTextRect(CFX_RectF& rect, | |
| 581 const CFX_WideString& text, | |
| 582 FX_BOOL isMultiline, | |
| 583 CFX_Matrix* matrix) { | |
| 584 switch (_type) { | |
| 585 case FX_CONTEXT_Device: { | |
| 586 if (!_renderDevice) | |
| 587 return FX_ERR_Property_Invalid; | |
| 588 int32_t length = text.GetLength(); | |
| 589 FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length); | |
| 590 FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length); | |
| 591 CalcTextInfo(text, charCodes, charPos, rect); | |
| 592 FX_Free(charPos); | |
| 593 FX_Free(charCodes); | |
| 594 return FX_ERR_Succeeded; | |
| 595 } | |
| 596 default: { return FX_ERR_Property_Invalid; } | |
| 597 } | |
| 598 } | |
| 599 FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics, | |
| 600 const CFX_Matrix* matrix) { | |
| 601 if (!graphics) | |
| 602 return FX_ERR_Parameter_Invalid; | |
| 603 CFX_Matrix m; | |
| 604 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, | |
| 605 _info._CTM.f); | |
| 606 if (matrix) { | |
| 607 m.Concat(*matrix); | |
| 608 } | |
| 609 switch (_type) { | |
| 610 case FX_CONTEXT_Device: { | |
| 611 if (!_renderDevice) | |
| 612 return FX_ERR_Property_Invalid; | |
| 613 { | |
| 614 if (!graphics->_renderDevice) | |
| 615 return FX_ERR_Parameter_Invalid; | |
| 616 CFX_DIBitmap* bitmap = graphics->_renderDevice->GetBitmap(); | |
| 617 FX_BOOL result = _renderDevice->SetDIBits(bitmap, 0, 0); | |
| 618 if (!result) | |
| 619 return FX_ERR_Method_Not_Supported; | |
| 620 } | |
| 621 } | |
| 622 default: { return FX_ERR_Property_Invalid; } | |
| 623 } | |
| 624 } | |
| 625 FX_ERR CFX_Graphics::Transfer(CFX_Graphics* graphics, | |
| 626 FX_FLOAT srcLeft, | |
| 627 FX_FLOAT srcTop, | |
| 628 const CFX_RectF& dstRect, | |
| 629 const CFX_Matrix* matrix) { | |
| 630 if (!graphics) | |
| 631 return FX_ERR_Parameter_Invalid; | |
| 632 CFX_Matrix m; | |
| 633 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, | |
| 634 _info._CTM.f); | |
| 635 if (matrix) { | |
| 636 m.Concat(*matrix); | |
| 637 } | |
| 638 switch (_type) { | |
| 639 case FX_CONTEXT_Device: { | |
| 640 if (!_renderDevice) | |
| 641 return FX_ERR_Property_Invalid; | |
| 642 { | |
| 643 if (!graphics->_renderDevice) | |
| 644 return FX_ERR_Parameter_Invalid; | |
| 645 CFX_DIBitmap* bitmap = graphics->_renderDevice->GetBitmap(); | |
| 646 CFX_DIBitmap bmp; | |
| 647 FX_BOOL result = | |
| 648 bmp.Create((int32_t)dstRect.width, (int32_t)dstRect.height, | |
| 649 bitmap->GetFormat()); | |
| 650 if (!result) | |
| 651 return FX_ERR_Intermediate_Value_Invalid; | |
| 652 result = graphics->_renderDevice->GetDIBits(&bmp, (int32_t)srcLeft, | |
| 653 (int32_t)srcTop); | |
| 654 if (!result) | |
| 655 return FX_ERR_Method_Not_Supported; | |
| 656 result = _renderDevice->SetDIBits(&bmp, (int32_t)dstRect.left, | |
| 657 (int32_t)dstRect.top); | |
| 658 if (!result) | |
| 659 return FX_ERR_Method_Not_Supported; | |
| 660 return FX_ERR_Succeeded; | |
| 661 } | |
| 662 } | |
| 663 default: { return FX_ERR_Property_Invalid; } | |
| 664 } | |
| 665 } | |
| 666 CFX_RenderDevice* CFX_Graphics::GetRenderDevice() { | |
| 667 return _renderDevice; | |
| 668 } | |
| 669 FX_ERR CFX_Graphics::InverseRect(const CFX_RectF& rect) { | |
| 670 if (!_renderDevice) | |
| 671 return FX_ERR_Property_Invalid; | |
| 672 CFX_DIBitmap* bitmap = _renderDevice->GetBitmap(); | |
| 673 if (!bitmap) | |
| 674 return FX_ERR_Property_Invalid; | |
| 675 CFX_RectF temp(rect); | |
| 676 _info._CTM.TransformRect(temp); | |
| 677 CFX_RectF r; | |
| 678 r.Set(0, 0, (FX_FLOAT)bitmap->GetWidth(), (FX_FLOAT)bitmap->GetWidth()); | |
| 679 r.Intersect(temp); | |
| 680 if (r.IsEmpty()) { | |
| 681 return FX_ERR_Parameter_Invalid; | |
| 682 } | |
| 683 FX_ARGB* pBuf = | |
| 684 (FX_ARGB*)(bitmap->GetBuffer() + int32_t(r.top) * bitmap->GetPitch()); | |
| 685 int32_t bottom = (int32_t)r.bottom(); | |
| 686 int32_t right = (int32_t)r.right(); | |
| 687 for (int32_t i = (int32_t)r.top; i < bottom; i++) { | |
| 688 FX_ARGB* pLine = pBuf + (int32_t)r.left; | |
| 689 for (int32_t j = (int32_t)r.left; j < right; j++) { | |
| 690 FX_ARGB c = *pLine; | |
| 691 *pLine++ = (c & 0xFF000000) | (0xFFFFFF - (c & 0x00FFFFFF)); | |
| 692 } | |
| 693 pBuf = (FX_ARGB*)((uint8_t*)pBuf + bitmap->GetPitch()); | |
| 694 } | |
| 695 return FX_ERR_Succeeded; | |
| 696 } | |
| 697 FX_ERR CFX_Graphics::XorDIBitmap(const CFX_DIBitmap* srcBitmap, | |
| 698 const CFX_RectF& rect) { | |
| 699 if (!_renderDevice) | |
| 700 return FX_ERR_Property_Invalid; | |
| 701 CFX_DIBitmap* dst = _renderDevice->GetBitmap(); | |
| 702 if (!dst) | |
| 703 return FX_ERR_Property_Invalid; | |
| 704 CFX_RectF temp(rect); | |
| 705 _info._CTM.TransformRect(temp); | |
| 706 CFX_RectF r; | |
| 707 r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth()); | |
| 708 r.Intersect(temp); | |
| 709 if (r.IsEmpty()) { | |
| 710 return FX_ERR_Parameter_Invalid; | |
| 711 } | |
| 712 FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() + | |
| 713 int32_t(r.top) * srcBitmap->GetPitch()); | |
| 714 FX_ARGB* pDstBuf = | |
| 715 (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch()); | |
| 716 int32_t bottom = (int32_t)r.bottom(); | |
| 717 int32_t right = (int32_t)r.right(); | |
| 718 for (int32_t i = (int32_t)r.top; i < bottom; i++) { | |
| 719 FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left; | |
| 720 FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left; | |
| 721 for (int32_t j = (int32_t)r.left; j < right; j++) { | |
| 722 FX_ARGB c = *pDstLine; | |
| 723 *pDstLine++ = | |
| 724 ArgbEncode(FXARGB_A(c), (c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF)); | |
| 725 pSrcLine++; | |
| 726 } | |
| 727 pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch()); | |
| 728 pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch()); | |
| 729 } | |
| 730 return FX_ERR_Succeeded; | |
| 731 } | |
| 732 FX_ERR CFX_Graphics::EqvDIBitmap(const CFX_DIBitmap* srcBitmap, | |
| 733 const CFX_RectF& rect) { | |
| 734 if (!_renderDevice) | |
| 735 return FX_ERR_Property_Invalid; | |
| 736 CFX_DIBitmap* dst = _renderDevice->GetBitmap(); | |
| 737 if (!dst) | |
| 738 return FX_ERR_Property_Invalid; | |
| 739 CFX_RectF temp(rect); | |
| 740 _info._CTM.TransformRect(temp); | |
| 741 CFX_RectF r; | |
| 742 r.Set(0, 0, (FX_FLOAT)dst->GetWidth(), (FX_FLOAT)dst->GetWidth()); | |
| 743 r.Intersect(temp); | |
| 744 if (r.IsEmpty()) { | |
| 745 return FX_ERR_Parameter_Invalid; | |
| 746 } | |
| 747 FX_ARGB* pSrcBuf = (FX_ARGB*)(srcBitmap->GetBuffer() + | |
| 748 int32_t(r.top) * srcBitmap->GetPitch()); | |
| 749 FX_ARGB* pDstBuf = | |
| 750 (FX_ARGB*)(dst->GetBuffer() + int32_t(r.top) * dst->GetPitch()); | |
| 751 int32_t bottom = (int32_t)r.bottom(); | |
| 752 int32_t right = (int32_t)r.right(); | |
| 753 for (int32_t i = (int32_t)r.top; i < bottom; i++) { | |
| 754 FX_ARGB* pSrcLine = pSrcBuf + (int32_t)r.left; | |
| 755 FX_ARGB* pDstLine = pDstBuf + (int32_t)r.left; | |
| 756 for (int32_t j = (int32_t)r.left; j < right; j++) { | |
| 757 FX_ARGB c = *pDstLine; | |
| 758 *pDstLine++ = | |
| 759 ArgbEncode(FXARGB_A(c), ~((c & 0xFFFFFF) ^ (*pSrcLine & 0xFFFFFF))); | |
| 760 pSrcLine++; | |
| 761 } | |
| 762 pSrcBuf = (FX_ARGB*)((uint8_t*)pSrcBuf + srcBitmap->GetPitch()); | |
| 763 pDstBuf = (FX_ARGB*)((uint8_t*)pDstBuf + dst->GetPitch()); | |
| 764 } | |
| 765 return FX_ERR_Succeeded; | |
| 766 } | |
| 767 FX_ERR CFX_Graphics::RenderDeviceSetLineDash(FX_DashStyle dashStyle) { | |
| 768 switch (dashStyle) { | |
| 769 case FX_DASHSTYLE_Solid: { | |
| 770 _info._graphState.SetDashCount(0); | |
| 771 return FX_ERR_Succeeded; | |
| 772 } | |
| 773 case FX_DASHSTYLE_Dash: { | |
| 774 FX_FLOAT dashArray[] = {3, 1}; | |
| 775 SetLineDash(0, dashArray, 2); | |
| 776 return FX_ERR_Succeeded; | |
| 777 } | |
| 778 case FX_DASHSTYLE_Dot: { | |
| 779 FX_FLOAT dashArray[] = {1, 1}; | |
| 780 SetLineDash(0, dashArray, 2); | |
| 781 return FX_ERR_Succeeded; | |
| 782 } | |
| 783 case FX_DASHSTYLE_DashDot: { | |
| 784 FX_FLOAT dashArray[] = {3, 1, 1, 1}; | |
| 785 SetLineDash(0, dashArray, 4); | |
| 786 return FX_ERR_Succeeded; | |
| 787 } | |
| 788 case FX_DASHSTYLE_DashDotDot: { | |
| 789 FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1}; | |
| 790 SetLineDash(0, dashArray, 6); | |
| 791 return FX_ERR_Succeeded; | |
| 792 } | |
| 793 default: { return FX_ERR_Parameter_Invalid; } | |
| 794 } | |
| 795 } | |
| 796 FX_ERR CFX_Graphics::RenderDeviceStrokePath(CFX_Path* path, | |
| 797 CFX_Matrix* matrix) { | |
| 798 if (!_info._strokeColor) | |
| 799 return FX_ERR_Property_Invalid; | |
| 800 CFX_Matrix m; | |
| 801 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, | |
| 802 _info._CTM.f); | |
| 803 if (matrix) { | |
| 804 m.Concat(*matrix); | |
| 805 } | |
| 806 switch (_info._strokeColor->_type) { | |
| 807 case FX_COLOR_Solid: { | |
| 808 FX_BOOL result = _renderDevice->DrawPath( | |
| 809 path->GetPathData(), (CFX_Matrix*)&m, &_info._graphState, 0x0, | |
| 810 _info._strokeColor->_argb, 0); | |
| 811 if (!result) | |
| 812 return FX_ERR_Indefinite; | |
| 813 return FX_ERR_Succeeded; | |
| 814 } | |
| 815 case FX_COLOR_Pattern: { | |
| 816 return StrokePathWithPattern(path, &m); | |
| 817 } | |
| 818 case FX_COLOR_Shading: { | |
| 819 return StrokePathWithShading(path, &m); | |
| 820 } | |
| 821 default: { return FX_ERR_Property_Invalid; } | |
| 822 } | |
| 823 } | |
| 824 FX_ERR CFX_Graphics::RenderDeviceFillPath(CFX_Path* path, | |
| 825 FX_FillMode fillMode, | |
| 826 CFX_Matrix* matrix) { | |
| 827 if (!_info._fillColor) | |
| 828 return FX_ERR_Property_Invalid; | |
| 829 CFX_Matrix m; | |
| 830 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, | |
| 831 _info._CTM.f); | |
| 832 if (matrix) { | |
| 833 m.Concat(*matrix); | |
| 834 } | |
| 835 switch (_info._fillColor->_type) { | |
| 836 case FX_COLOR_Solid: { | |
| 837 FX_BOOL result = _renderDevice->DrawPath( | |
| 838 path->GetPathData(), (CFX_Matrix*)&m, &_info._graphState, | |
| 839 _info._fillColor->_argb, 0x0, fillMode); | |
| 840 if (!result) | |
| 841 return FX_ERR_Indefinite; | |
| 842 return FX_ERR_Succeeded; | |
| 843 } | |
| 844 case FX_COLOR_Pattern: { | |
| 845 { return FillPathWithPattern(path, fillMode, &m); } | |
| 846 } | |
| 847 case FX_COLOR_Shading: { | |
| 848 { return FillPathWithShading(path, fillMode, &m); } | |
| 849 } | |
| 850 default: { return FX_ERR_Property_Invalid; } | |
| 851 } | |
| 852 } | |
| 853 FX_ERR CFX_Graphics::RenderDeviceDrawImage(CFX_DIBSource* source, | |
| 854 const CFX_PointF& point, | |
| 855 CFX_Matrix* matrix) { | |
| 856 CFX_Matrix m1; | |
| 857 m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, | |
| 858 _info._CTM.f); | |
| 859 if (matrix) { | |
| 860 m1.Concat(*matrix); | |
| 861 } | |
| 862 CFX_Matrix m2; | |
| 863 m2.Set((FX_FLOAT)source->GetWidth(), 0.0, 0.0, (FX_FLOAT)source->GetHeight(), | |
| 864 point.x, point.y); | |
| 865 m2.Concat(m1); | |
| 866 int32_t left, top; | |
| 867 CFX_DIBitmap* bmp1 = source->FlipImage(FALSE, TRUE); | |
| 868 CFX_DIBitmap* bmp2 = bmp1->TransformTo((CFX_Matrix*)&m2, left, top); | |
| 869 CFX_RectF r; | |
| 870 GetClipRect(r); | |
| 871 FX_ERR result = FX_ERR_Indefinite; | |
| 872 { | |
| 873 CFX_DIBitmap* bitmap = _renderDevice->GetBitmap(); | |
| 874 CFX_DIBitmap bmp; | |
| 875 bmp.Create(bitmap->GetWidth(), bitmap->GetHeight(), FXDIB_Argb); | |
| 876 _renderDevice->GetDIBits(&bmp, 0, 0); | |
| 877 bmp.TransferBitmap(FXSYS_round(r.left), FXSYS_round(r.top), | |
| 878 FXSYS_round(r.Width()), FXSYS_round(r.Height()), bmp2, | |
| 879 FXSYS_round(r.left - left), FXSYS_round(r.top - top)); | |
| 880 _renderDevice->SetDIBits(&bmp, 0, 0); | |
| 881 result = FX_ERR_Succeeded; | |
| 882 } | |
| 883 if (bmp2) { | |
| 884 delete bmp2; | |
| 885 bmp2 = NULL; | |
| 886 } | |
| 887 if (bmp1) { | |
| 888 delete bmp1; | |
| 889 bmp1 = NULL; | |
| 890 } | |
| 891 return result; | |
| 892 } | |
| 893 FX_ERR CFX_Graphics::RenderDeviceStretchImage(CFX_DIBSource* source, | |
| 894 const CFX_RectF& rect, | |
| 895 CFX_Matrix* matrix) { | |
| 896 CFX_Matrix m1; | |
| 897 m1.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, | |
| 898 _info._CTM.f); | |
| 899 if (matrix) { | |
| 900 m1.Concat(*matrix); | |
| 901 } | |
| 902 CFX_DIBitmap* bmp1 = | |
| 903 source->StretchTo((int32_t)rect.Width(), (int32_t)rect.Height()); | |
| 904 CFX_Matrix m2; | |
| 905 m2.Set(rect.Width(), 0.0, 0.0, rect.Height(), rect.left, rect.top); | |
| 906 m2.Concat(m1); | |
| 907 int32_t left, top; | |
| 908 CFX_DIBitmap* bmp2 = bmp1->FlipImage(FALSE, TRUE); | |
| 909 CFX_DIBitmap* bmp3 = bmp2->TransformTo((CFX_Matrix*)&m2, left, top); | |
| 910 CFX_RectF r; | |
| 911 GetClipRect(r); | |
| 912 FX_ERR result = FX_ERR_Indefinite; | |
| 913 { | |
| 914 CFX_DIBitmap* bitmap = _renderDevice->GetBitmap(); | |
| 915 bitmap->CompositeBitmap(FXSYS_round(r.left), FXSYS_round(r.top), | |
| 916 FXSYS_round(r.Width()), FXSYS_round(r.Height()), | |
| 917 bmp3, FXSYS_round(r.left - left), | |
| 918 FXSYS_round(r.top - top)); | |
| 919 result = FX_ERR_Succeeded; | |
| 920 } | |
| 921 if (bmp3) { | |
| 922 delete bmp3; | |
| 923 bmp3 = NULL; | |
| 924 } | |
| 925 if (bmp2) { | |
| 926 delete bmp2; | |
| 927 bmp2 = NULL; | |
| 928 } | |
| 929 if (bmp1) { | |
| 930 delete bmp1; | |
| 931 bmp1 = NULL; | |
| 932 } | |
| 933 return result; | |
| 934 } | |
| 935 FX_ERR CFX_Graphics::RenderDeviceShowText(const CFX_PointF& point, | |
| 936 const CFX_WideString& text, | |
| 937 CFX_Matrix* matrix) { | |
| 938 int32_t length = text.GetLength(); | |
| 939 FX_DWORD* charCodes = FX_Alloc(FX_DWORD, length); | |
| 940 FXTEXT_CHARPOS* charPos = FX_Alloc(FXTEXT_CHARPOS, length); | |
| 941 CFX_RectF rect; | |
| 942 rect.Set(point.x, point.y, 0, 0); | |
| 943 CalcTextInfo(text, charCodes, charPos, rect); | |
| 944 CFX_Matrix m; | |
| 945 m.Set(_info._CTM.a, _info._CTM.b, _info._CTM.c, _info._CTM.d, _info._CTM.e, | |
| 946 _info._CTM.f); | |
| 947 m.Translate(0, _info._fontSize * _info._fontHScale); | |
| 948 if (matrix) { | |
| 949 m.Concat(*matrix); | |
| 950 } | |
| 951 FX_BOOL result = _renderDevice->DrawNormalText( | |
| 952 length, charPos, _info._font, CFX_GEModule::Get()->GetFontCache(), | |
| 953 -_info._fontSize * _info._fontHScale, (CFX_Matrix*)&m, | |
| 954 _info._fillColor->_argb, FXTEXT_CLEARTYPE); | |
| 955 if (!result) | |
| 956 return FX_ERR_Indefinite; | |
| 957 FX_Free(charPos); | |
| 958 FX_Free(charCodes); | |
| 959 return FX_ERR_Succeeded; | |
| 960 } | |
| 961 FX_ERR CFX_Graphics::StrokePathWithPattern(CFX_Path* path, CFX_Matrix* matrix) { | |
| 962 return FX_ERR_Method_Not_Supported; | |
| 963 } | |
| 964 FX_ERR CFX_Graphics::StrokePathWithShading(CFX_Path* path, CFX_Matrix* matrix) { | |
| 965 return FX_ERR_Method_Not_Supported; | |
| 966 } | |
| 967 FX_ERR CFX_Graphics::FillPathWithPattern(CFX_Path* path, | |
| 968 FX_FillMode fillMode, | |
| 969 CFX_Matrix* matrix) { | |
| 970 CFX_Pattern* pattern = _info._fillColor->_pattern; | |
| 971 CFX_DIBitmap* bitmap = _renderDevice->GetBitmap(); | |
| 972 int32_t width = bitmap->GetWidth(); | |
| 973 int32_t height = bitmap->GetHeight(); | |
| 974 CFX_DIBitmap bmp; | |
| 975 bmp.Create(width, height, FXDIB_Argb); | |
| 976 _renderDevice->GetDIBits(&bmp, 0, 0); | |
| 977 switch (pattern->_type) { | |
| 978 case FX_PATTERN_Bitmap: { | |
| 979 int32_t xStep = FXSYS_round(pattern->_x1Step); | |
| 980 int32_t yStep = FXSYS_round(pattern->_y1Step); | |
| 981 int32_t xCount = width / xStep + 1; | |
| 982 int32_t yCount = height / yStep + 1; | |
| 983 for (int32_t i = 0; i <= yCount; i++) { | |
| 984 for (int32_t j = 0; j <= xCount; j++) { | |
| 985 bmp.TransferBitmap(j * xStep, i * yStep, xStep, yStep, | |
| 986 pattern->_bitmap, 0, 0); | |
| 987 } | |
| 988 } | |
| 989 break; | |
| 990 } | |
| 991 case FX_PATTERN_Hatch: { | |
| 992 FX_HatchStyle hatchStyle = _info._fillColor->_pattern->_hatchStyle; | |
| 993 if (hatchStyle < FX_HATCHSTYLE_Horizontal || | |
| 994 hatchStyle > FX_HATCHSTYLE_SolidDiamond) { | |
| 995 return FX_ERR_Intermediate_Value_Invalid; | |
| 996 } | |
| 997 const FX_HATCHDATA& data = hatchBitmapData[hatchStyle]; | |
| 998 CFX_DIBitmap mask; | |
| 999 mask.Create(data.width, data.height, FXDIB_1bppMask); | |
| 1000 FXSYS_memcpy(mask.GetBuffer(), data.maskBits, | |
| 1001 mask.GetPitch() * data.height); | |
| 1002 CFX_FloatRect rectf = path->GetPathData()->GetBoundingBox(); | |
| 1003 if (matrix) { | |
| 1004 rectf.Transform((const CFX_Matrix*)matrix); | |
| 1005 } | |
| 1006 FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top), | |
| 1007 FXSYS_round(rectf.right), FXSYS_round(rectf.bottom)); | |
| 1008 CFX_FxgeDevice device; | |
| 1009 device.Attach(&bmp); | |
| 1010 device.FillRect(&rect, _info._fillColor->_pattern->_backArgb); | |
| 1011 for (int32_t j = rect.bottom; j < rect.top; j += mask.GetHeight()) { | |
| 1012 for (int32_t i = rect.left; i < rect.right; i += mask.GetWidth()) { | |
| 1013 device.SetBitMask(&mask, i, j, _info._fillColor->_pattern->_foreArgb); | |
| 1014 } | |
| 1015 } | |
| 1016 break; | |
| 1017 } | |
| 1018 } | |
| 1019 _renderDevice->SaveState(); | |
| 1020 _renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix, | |
| 1021 fillMode); | |
| 1022 SetDIBitsWithMatrix(&bmp, &pattern->_matrix); | |
| 1023 _renderDevice->RestoreState(); | |
| 1024 return FX_ERR_Succeeded; | |
| 1025 } | |
| 1026 FX_ERR CFX_Graphics::FillPathWithShading(CFX_Path* path, | |
| 1027 FX_FillMode fillMode, | |
| 1028 CFX_Matrix* matrix) { | |
| 1029 CFX_DIBitmap* bitmap = _renderDevice->GetBitmap(); | |
| 1030 int32_t width = bitmap->GetWidth(); | |
| 1031 int32_t height = bitmap->GetHeight(); | |
| 1032 FX_FLOAT start_x = _info._fillColor->_shading->_beginPoint.x; | |
| 1033 FX_FLOAT start_y = _info._fillColor->_shading->_beginPoint.y; | |
| 1034 FX_FLOAT end_x = _info._fillColor->_shading->_endPoint.x; | |
| 1035 FX_FLOAT end_y = _info._fillColor->_shading->_endPoint.y; | |
| 1036 CFX_DIBitmap bmp; | |
| 1037 bmp.Create(width, height, FXDIB_Argb); | |
| 1038 _renderDevice->GetDIBits(&bmp, 0, 0); | |
| 1039 int32_t pitch = bmp.GetPitch(); | |
| 1040 FX_BOOL result = FALSE; | |
| 1041 switch (_info._fillColor->_shading->_type) { | |
| 1042 case FX_SHADING_Axial: { | |
| 1043 FX_FLOAT x_span = end_x - start_x; | |
| 1044 FX_FLOAT y_span = end_y - start_y; | |
| 1045 FX_FLOAT axis_len_square = (x_span * x_span) + (y_span * y_span); | |
| 1046 for (int32_t row = 0; row < height; row++) { | |
| 1047 FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch); | |
| 1048 for (int32_t column = 0; column < width; column++) { | |
| 1049 FX_FLOAT x = (FX_FLOAT)(column); | |
| 1050 FX_FLOAT y = (FX_FLOAT)(row); | |
| 1051 FX_FLOAT scale = | |
| 1052 (((x - start_x) * x_span) + ((y - start_y) * y_span)) / | |
| 1053 axis_len_square; | |
| 1054 if (scale < 0) { | |
| 1055 if (!_info._fillColor->_shading->_isExtendedBegin) { | |
| 1056 continue; | |
| 1057 } | |
| 1058 scale = 0; | |
| 1059 } else if (scale > 1.0f) { | |
| 1060 if (!_info._fillColor->_shading->_isExtendedEnd) { | |
| 1061 continue; | |
| 1062 } | |
| 1063 scale = 1.0f; | |
| 1064 } | |
| 1065 int32_t index = (int32_t)(scale * (FX_SHADING_Steps - 1)); | |
| 1066 dib_buf[column] = _info._fillColor->_shading->_argbArray[index]; | |
| 1067 } | |
| 1068 } | |
| 1069 result = TRUE; | |
| 1070 break; | |
| 1071 } | |
| 1072 case FX_SHADING_Radial: { | |
| 1073 FX_FLOAT start_r = _info._fillColor->_shading->_beginRadius; | |
| 1074 FX_FLOAT end_r = _info._fillColor->_shading->_endRadius; | |
| 1075 FX_FLOAT a = ((start_x - end_x) * (start_x - end_x)) + | |
| 1076 ((start_y - end_y) * (start_y - end_y)) - | |
| 1077 ((start_r - end_r) * (start_r - end_r)); | |
| 1078 for (int32_t row = 0; row < height; row++) { | |
| 1079 FX_DWORD* dib_buf = (FX_DWORD*)(bmp.GetBuffer() + row * pitch); | |
| 1080 for (int32_t column = 0; column < width; column++) { | |
| 1081 FX_FLOAT x = (FX_FLOAT)(column); | |
| 1082 FX_FLOAT y = (FX_FLOAT)(row); | |
| 1083 FX_FLOAT b = -2 * (((x - start_x) * (end_x - start_x)) + | |
| 1084 ((y - start_y) * (end_y - start_y)) + | |
| 1085 (start_r * (end_r - start_r))); | |
| 1086 FX_FLOAT c = ((x - start_x) * (x - start_x)) + | |
| 1087 ((y - start_y) * (y - start_y)) - (start_r * start_r); | |
| 1088 FX_FLOAT s; | |
| 1089 if (a == 0) { | |
| 1090 s = -c / b; | |
| 1091 } else { | |
| 1092 FX_FLOAT b2_4ac = (b * b) - 4 * (a * c); | |
| 1093 if (b2_4ac < 0) { | |
| 1094 continue; | |
| 1095 } | |
| 1096 FX_FLOAT root = (FXSYS_sqrt(b2_4ac)); | |
| 1097 FX_FLOAT s1, s2; | |
| 1098 if (a > 0) { | |
| 1099 s1 = (-b - root) / (2 * a); | |
| 1100 s2 = (-b + root) / (2 * a); | |
| 1101 } else { | |
| 1102 s2 = (-b - root) / (2 * a); | |
| 1103 s1 = (-b + root) / (2 * a); | |
| 1104 } | |
| 1105 if (s2 <= 1.0f || _info._fillColor->_shading->_isExtendedEnd) { | |
| 1106 s = (s2); | |
| 1107 } else { | |
| 1108 s = (s1); | |
| 1109 } | |
| 1110 if ((start_r) + s * (end_r - start_r) < 0) { | |
| 1111 continue; | |
| 1112 } | |
| 1113 } | |
| 1114 if (s < 0) { | |
| 1115 if (!_info._fillColor->_shading->_isExtendedBegin) { | |
| 1116 continue; | |
| 1117 } | |
| 1118 s = 0; | |
| 1119 } | |
| 1120 if (s > 1.0f) { | |
| 1121 if (!_info._fillColor->_shading->_isExtendedEnd) { | |
| 1122 continue; | |
| 1123 } | |
| 1124 s = 1.0f; | |
| 1125 } | |
| 1126 int index = (int32_t)(s * (FX_SHADING_Steps - 1)); | |
| 1127 dib_buf[column] = _info._fillColor->_shading->_argbArray[index]; | |
| 1128 } | |
| 1129 } | |
| 1130 result = TRUE; | |
| 1131 break; | |
| 1132 } | |
| 1133 default: { result = FALSE; } | |
| 1134 } | |
| 1135 if (result) { | |
| 1136 _renderDevice->SaveState(); | |
| 1137 _renderDevice->SetClip_PathFill(path->GetPathData(), (CFX_Matrix*)matrix, | |
| 1138 fillMode); | |
| 1139 SetDIBitsWithMatrix(&bmp, matrix); | |
| 1140 _renderDevice->RestoreState(); | |
| 1141 } | |
| 1142 return result; | |
| 1143 } | |
| 1144 FX_ERR CFX_Graphics::SetDIBitsWithMatrix(CFX_DIBSource* source, | |
| 1145 CFX_Matrix* matrix) { | |
| 1146 if (matrix->IsIdentity()) { | |
| 1147 _renderDevice->SetDIBits(source, 0, 0); | |
| 1148 } else { | |
| 1149 CFX_Matrix m; | |
| 1150 m.Set((FX_FLOAT)source->GetWidth(), 0, 0, (FX_FLOAT)source->GetHeight(), 0, | |
| 1151 0); | |
| 1152 m.Concat(*matrix); | |
| 1153 int32_t left, top; | |
| 1154 CFX_DIBitmap* bmp1 = source->FlipImage(FALSE, TRUE); | |
| 1155 CFX_DIBitmap* bmp2 = bmp1->TransformTo((CFX_Matrix*)&m, left, top); | |
| 1156 _renderDevice->SetDIBits(bmp2, left, top); | |
| 1157 if (bmp2) { | |
| 1158 delete bmp2; | |
| 1159 bmp2 = NULL; | |
| 1160 } | |
| 1161 if (bmp1) { | |
| 1162 delete bmp1; | |
| 1163 bmp1 = NULL; | |
| 1164 } | |
| 1165 } | |
| 1166 return FX_ERR_Succeeded; | |
| 1167 } | |
| 1168 FX_ERR CFX_Graphics::CalcTextInfo(const CFX_WideString& text, | |
| 1169 FX_DWORD* charCodes, | |
| 1170 FXTEXT_CHARPOS* charPos, | |
| 1171 CFX_RectF& rect) { | |
| 1172 std::unique_ptr<CFX_UnicodeEncoding> encoding( | |
| 1173 new CFX_UnicodeEncoding(_info._font)); | |
| 1174 int32_t length = text.GetLength(); | |
| 1175 FX_FLOAT penX = (FX_FLOAT)rect.left; | |
| 1176 FX_FLOAT penY = (FX_FLOAT)rect.top; | |
| 1177 FX_FLOAT left = (FX_FLOAT)(0); | |
| 1178 FX_FLOAT top = (FX_FLOAT)(0); | |
| 1179 charCodes[0] = text.GetAt(0); | |
| 1180 charPos[0].m_OriginX = penX + left; | |
| 1181 charPos[0].m_OriginY = penY + top; | |
| 1182 charPos[0].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[0]); | |
| 1183 charPos[0].m_FontCharWidth = FXSYS_round( | |
| 1184 _info._font->GetGlyphWidth(charPos[0].m_GlyphIndex) * _info._fontHScale); | |
| 1185 charPos[0].m_bGlyphAdjust = TRUE; | |
| 1186 charPos[0].m_AdjustMatrix[0] = -1; | |
| 1187 charPos[0].m_AdjustMatrix[1] = 0; | |
| 1188 charPos[0].m_AdjustMatrix[2] = 0; | |
| 1189 charPos[0].m_AdjustMatrix[3] = 1; | |
| 1190 penX += (FX_FLOAT)(charPos[0].m_FontCharWidth) * _info._fontSize / 1000 + | |
| 1191 _info._fontSpacing; | |
| 1192 for (int32_t i = 1; i < length; i++) { | |
| 1193 charCodes[i] = text.GetAt(i); | |
| 1194 charPos[i].m_OriginX = penX + left; | |
| 1195 charPos[i].m_OriginY = penY + top; | |
| 1196 charPos[i].m_GlyphIndex = encoding->GlyphFromCharCode(charCodes[i]); | |
| 1197 charPos[i].m_FontCharWidth = | |
| 1198 FXSYS_round(_info._font->GetGlyphWidth(charPos[i].m_GlyphIndex) * | |
| 1199 _info._fontHScale); | |
| 1200 charPos[i].m_bGlyphAdjust = TRUE; | |
| 1201 charPos[i].m_AdjustMatrix[0] = -1; | |
| 1202 charPos[i].m_AdjustMatrix[1] = 0; | |
| 1203 charPos[i].m_AdjustMatrix[2] = 0; | |
| 1204 charPos[i].m_AdjustMatrix[3] = 1; | |
| 1205 penX += (FX_FLOAT)(charPos[i].m_FontCharWidth) * _info._fontSize / 1000 + | |
| 1206 _info._fontSpacing; | |
| 1207 } | |
| 1208 rect.width = (FX_FLOAT)penX - rect.left; | |
| 1209 rect.height = rect.top + _info._fontSize * _info._fontHScale - rect.top; | |
| 1210 return FX_ERR_Succeeded; | |
| 1211 } | |
| 1212 CAGG_Graphics::CAGG_Graphics() { | |
| 1213 _owner = NULL; | |
| 1214 } | |
| 1215 FX_ERR CAGG_Graphics::Create(CFX_Graphics* owner, | |
| 1216 int32_t width, | |
| 1217 int32_t height, | |
| 1218 FXDIB_Format format) { | |
| 1219 if (owner->_renderDevice) { | |
| 1220 return FX_ERR_Parameter_Invalid; | |
| 1221 } | |
| 1222 if (_owner) { | |
| 1223 return FX_ERR_Property_Invalid; | |
| 1224 } | |
| 1225 CFX_FxgeDevice* device = new CFX_FxgeDevice; | |
| 1226 device->Create(width, height, format); | |
| 1227 _owner = owner; | |
| 1228 _owner->_renderDevice = device; | |
| 1229 _owner->_renderDevice->GetBitmap()->Clear(0xFFFFFFFF); | |
| 1230 return FX_ERR_Succeeded; | |
| 1231 } | |
| 1232 CAGG_Graphics::~CAGG_Graphics() { | |
| 1233 if (_owner->_renderDevice) { | |
| 1234 delete (CFX_FxgeDevice*)_owner->_renderDevice; | |
| 1235 } | |
| 1236 _owner = NULL; | |
| 1237 } | |
| 1238 CFX_Path::CFX_Path() { | |
| 1239 _generator = NULL; | |
| 1240 } | |
| 1241 FX_ERR CFX_Path::Create() { | |
| 1242 if (_generator) { | |
| 1243 return FX_ERR_Property_Invalid; | |
| 1244 } | |
| 1245 _generator = new CFX_PathGenerator; | |
| 1246 _generator->Create(); | |
| 1247 return FX_ERR_Succeeded; | |
| 1248 } | |
| 1249 CFX_Path::~CFX_Path() { | |
| 1250 if (_generator) { | |
| 1251 delete _generator; | |
| 1252 _generator = NULL; | |
| 1253 } | |
| 1254 } | |
| 1255 FX_ERR CFX_Path::MoveTo(FX_FLOAT x, FX_FLOAT y) { | |
| 1256 if (!_generator) | |
| 1257 return FX_ERR_Property_Invalid; | |
| 1258 _generator->MoveTo(x, y); | |
| 1259 return FX_ERR_Succeeded; | |
| 1260 } | |
| 1261 FX_ERR CFX_Path::LineTo(FX_FLOAT x, FX_FLOAT y) { | |
| 1262 if (!_generator) | |
| 1263 return FX_ERR_Property_Invalid; | |
| 1264 _generator->LineTo(x, y); | |
| 1265 return FX_ERR_Succeeded; | |
| 1266 } | |
| 1267 FX_ERR CFX_Path::BezierTo(FX_FLOAT ctrlX1, | |
| 1268 FX_FLOAT ctrlY1, | |
| 1269 FX_FLOAT ctrlX2, | |
| 1270 FX_FLOAT ctrlY2, | |
| 1271 FX_FLOAT toX, | |
| 1272 FX_FLOAT toY) { | |
| 1273 if (!_generator) | |
| 1274 return FX_ERR_Property_Invalid; | |
| 1275 _generator->BezierTo(ctrlX1, ctrlY1, ctrlX2, ctrlY2, toX, toY); | |
| 1276 return FX_ERR_Succeeded; | |
| 1277 } | |
| 1278 FX_ERR CFX_Path::ArcTo(FX_FLOAT left, | |
| 1279 FX_FLOAT top, | |
| 1280 FX_FLOAT width, | |
| 1281 FX_FLOAT height, | |
| 1282 FX_FLOAT startAngle, | |
| 1283 FX_FLOAT sweepAngle) { | |
| 1284 if (!_generator) | |
| 1285 return FX_ERR_Property_Invalid; | |
| 1286 _generator->ArcTo(left + width / 2, top + height / 2, width / 2, height / 2, | |
| 1287 startAngle, sweepAngle); | |
| 1288 return FX_ERR_Succeeded; | |
| 1289 } | |
| 1290 FX_ERR CFX_Path::Close() { | |
| 1291 if (!_generator) | |
| 1292 return FX_ERR_Property_Invalid; | |
| 1293 _generator->Close(); | |
| 1294 return FX_ERR_Succeeded; | |
| 1295 } | |
| 1296 FX_ERR CFX_Path::AddLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2) { | |
| 1297 if (!_generator) | |
| 1298 return FX_ERR_Property_Invalid; | |
| 1299 _generator->AddLine(x1, y1, x2, y2); | |
| 1300 return FX_ERR_Succeeded; | |
| 1301 } | |
| 1302 FX_ERR CFX_Path::AddBezier(FX_FLOAT startX, | |
| 1303 FX_FLOAT startY, | |
| 1304 FX_FLOAT ctrlX1, | |
| 1305 FX_FLOAT ctrlY1, | |
| 1306 FX_FLOAT ctrlX2, | |
| 1307 FX_FLOAT ctrlY2, | |
| 1308 FX_FLOAT endX, | |
| 1309 FX_FLOAT endY) { | |
| 1310 if (!_generator) | |
| 1311 return FX_ERR_Property_Invalid; | |
| 1312 _generator->AddBezier(startX, startY, ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, | |
| 1313 endY); | |
| 1314 return FX_ERR_Succeeded; | |
| 1315 } | |
| 1316 FX_ERR CFX_Path::AddRectangle(FX_FLOAT left, | |
| 1317 FX_FLOAT top, | |
| 1318 FX_FLOAT width, | |
| 1319 FX_FLOAT height) { | |
| 1320 if (!_generator) | |
| 1321 return FX_ERR_Property_Invalid; | |
| 1322 _generator->AddRectangle(left, top, left + width, top + height); | |
| 1323 return FX_ERR_Succeeded; | |
| 1324 } | |
| 1325 FX_ERR CFX_Path::AddEllipse(FX_FLOAT left, | |
| 1326 FX_FLOAT top, | |
| 1327 FX_FLOAT width, | |
| 1328 FX_FLOAT height) { | |
| 1329 if (!_generator) | |
| 1330 return FX_ERR_Property_Invalid; | |
| 1331 _generator->AddEllipse(left + width / 2, top + height / 2, width / 2, | |
| 1332 height / 2); | |
| 1333 return FX_ERR_Succeeded; | |
| 1334 } | |
| 1335 FX_ERR CFX_Path::AddEllipse(const CFX_RectF& rect) { | |
| 1336 if (!_generator) | |
| 1337 return FX_ERR_Property_Invalid; | |
| 1338 _generator->AddEllipse(rect.left + rect.Width() / 2, | |
| 1339 rect.top + rect.Height() / 2, rect.Width() / 2, | |
| 1340 rect.Height() / 2); | |
| 1341 return FX_ERR_Succeeded; | |
| 1342 } | |
| 1343 FX_ERR CFX_Path::AddArc(FX_FLOAT left, | |
| 1344 FX_FLOAT top, | |
| 1345 FX_FLOAT width, | |
| 1346 FX_FLOAT height, | |
| 1347 FX_FLOAT startAngle, | |
| 1348 FX_FLOAT sweepAngle) { | |
| 1349 if (!_generator) | |
| 1350 return FX_ERR_Property_Invalid; | |
| 1351 _generator->AddArc(left + width / 2, top + height / 2, width / 2, height / 2, | |
| 1352 startAngle, sweepAngle); | |
| 1353 return FX_ERR_Succeeded; | |
| 1354 } | |
| 1355 FX_ERR CFX_Path::AddPie(FX_FLOAT left, | |
| 1356 FX_FLOAT top, | |
| 1357 FX_FLOAT width, | |
| 1358 FX_FLOAT height, | |
| 1359 FX_FLOAT startAngle, | |
| 1360 FX_FLOAT sweepAngle) { | |
| 1361 if (!_generator) | |
| 1362 return FX_ERR_Property_Invalid; | |
| 1363 _generator->AddPie(left + width / 2, top + height / 2, width / 2, height / 2, | |
| 1364 startAngle, sweepAngle); | |
| 1365 return FX_ERR_Succeeded; | |
| 1366 } | |
| 1367 FX_ERR CFX_Path::AddSubpath(CFX_Path* path) { | |
| 1368 if (!_generator) | |
| 1369 return FX_ERR_Property_Invalid; | |
| 1370 _generator->AddPathData(path->GetPathData()); | |
| 1371 return FX_ERR_Succeeded; | |
| 1372 } | |
| 1373 FX_ERR CFX_Path::Clear() { | |
| 1374 if (!_generator) | |
| 1375 return FX_ERR_Property_Invalid; | |
| 1376 _generator->GetPathData()->SetPointCount(0); | |
| 1377 return FX_ERR_Succeeded; | |
| 1378 } | |
| 1379 FX_BOOL CFX_Path::IsEmpty() { | |
| 1380 if (!_generator) | |
| 1381 return FX_ERR_Property_Invalid; | |
| 1382 if (_generator->GetPathData()->GetPointCount() == 0) { | |
| 1383 return TRUE; | |
| 1384 } | |
| 1385 return FALSE; | |
| 1386 } | |
| 1387 CFX_PathData* CFX_Path::GetPathData() { | |
| 1388 if (!_generator) | |
| 1389 return NULL; | |
| 1390 return _generator->GetPathData(); | |
| 1391 } | |
| 1392 CFX_Color::CFX_Color() { | |
| 1393 _type = FX_COLOR_None; | |
| 1394 } | |
| 1395 CFX_Color::CFX_Color(const FX_ARGB argb) { | |
| 1396 _type = FX_COLOR_None; | |
| 1397 Set(argb); | |
| 1398 } | |
| 1399 CFX_Color::CFX_Color(CFX_Pattern* pattern, const FX_ARGB argb) { | |
| 1400 _type = FX_COLOR_None; | |
| 1401 Set(pattern, argb); | |
| 1402 } | |
| 1403 CFX_Color::CFX_Color(CFX_Shading* shading) { | |
| 1404 _type = FX_COLOR_None; | |
| 1405 Set(shading); | |
| 1406 } | |
| 1407 CFX_Color::~CFX_Color() { | |
| 1408 _type = FX_COLOR_None; | |
| 1409 } | |
| 1410 FX_ERR CFX_Color::Set(const FX_ARGB argb) { | |
| 1411 _type = FX_COLOR_Solid; | |
| 1412 _argb = argb; | |
| 1413 _pattern = NULL; | |
| 1414 return FX_ERR_Succeeded; | |
| 1415 } | |
| 1416 FX_ERR CFX_Color::Set(CFX_Pattern* pattern, const FX_ARGB argb) { | |
| 1417 if (!pattern) | |
| 1418 return FX_ERR_Parameter_Invalid; | |
| 1419 _type = FX_COLOR_Pattern; | |
| 1420 _argb = argb; | |
| 1421 _pattern = pattern; | |
| 1422 return FX_ERR_Succeeded; | |
| 1423 } | |
| 1424 FX_ERR CFX_Color::Set(CFX_Shading* shading) { | |
| 1425 if (!shading) | |
| 1426 return FX_ERR_Parameter_Invalid; | |
| 1427 _type = FX_COLOR_Shading; | |
| 1428 _shading = shading; | |
| 1429 return FX_ERR_Succeeded; | |
| 1430 } | |
| 1431 CFX_Pattern::CFX_Pattern() { | |
| 1432 _type = FX_PATTERN_None; | |
| 1433 _matrix.SetIdentity(); | |
| 1434 } | |
| 1435 FX_ERR CFX_Pattern::Create(CFX_DIBitmap* bitmap, | |
| 1436 const FX_FLOAT xStep, | |
| 1437 const FX_FLOAT yStep, | |
| 1438 CFX_Matrix* matrix) { | |
| 1439 if (!bitmap) | |
| 1440 return FX_ERR_Parameter_Invalid; | |
| 1441 if (_type != FX_PATTERN_None) { | |
| 1442 return FX_ERR_Property_Invalid; | |
| 1443 } | |
| 1444 _type = FX_PATTERN_Bitmap; | |
| 1445 _bitmap = bitmap; | |
| 1446 _x1Step = xStep; | |
| 1447 _y1Step = yStep; | |
| 1448 if (matrix) { | |
| 1449 _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, | |
| 1450 matrix->f); | |
| 1451 } | |
| 1452 return FX_ERR_Succeeded; | |
| 1453 } | |
| 1454 FX_ERR CFX_Pattern::Create(FX_HatchStyle hatchStyle, | |
| 1455 const FX_ARGB foreArgb, | |
| 1456 const FX_ARGB backArgb, | |
| 1457 CFX_Matrix* matrix) { | |
| 1458 if (hatchStyle < FX_HATCHSTYLE_Horizontal || | |
| 1459 hatchStyle > FX_HATCHSTYLE_SolidDiamond) { | |
| 1460 return FX_ERR_Parameter_Invalid; | |
| 1461 } | |
| 1462 if (_type != FX_PATTERN_None) { | |
| 1463 return FX_ERR_Property_Invalid; | |
| 1464 } | |
| 1465 _type = FX_PATTERN_Hatch; | |
| 1466 _hatchStyle = hatchStyle; | |
| 1467 _foreArgb = foreArgb; | |
| 1468 _backArgb = backArgb; | |
| 1469 if (matrix) { | |
| 1470 _matrix.Set(matrix->a, matrix->b, matrix->c, matrix->d, matrix->e, | |
| 1471 matrix->f); | |
| 1472 } | |
| 1473 return FX_ERR_Succeeded; | |
| 1474 } | |
| 1475 CFX_Pattern::~CFX_Pattern() { | |
| 1476 _type = FX_PATTERN_None; | |
| 1477 } | |
| 1478 CFX_Shading::CFX_Shading() { | |
| 1479 _type = FX_SHADING_None; | |
| 1480 } | |
| 1481 FX_ERR CFX_Shading::CreateAxial(const CFX_PointF& beginPoint, | |
| 1482 const CFX_PointF& endPoint, | |
| 1483 FX_BOOL isExtendedBegin, | |
| 1484 FX_BOOL isExtendedEnd, | |
| 1485 const FX_ARGB beginArgb, | |
| 1486 const FX_ARGB endArgb) { | |
| 1487 if (_type != FX_SHADING_None) { | |
| 1488 return FX_ERR_Property_Invalid; | |
| 1489 } | |
| 1490 _type = FX_SHADING_Axial; | |
| 1491 _beginPoint = beginPoint; | |
| 1492 _endPoint = endPoint; | |
| 1493 _isExtendedBegin = isExtendedBegin; | |
| 1494 _isExtendedEnd = isExtendedEnd; | |
| 1495 _beginArgb = beginArgb; | |
| 1496 _endArgb = endArgb; | |
| 1497 return InitArgbArray(); | |
| 1498 } | |
| 1499 FX_ERR CFX_Shading::CreateRadial(const CFX_PointF& beginPoint, | |
| 1500 const CFX_PointF& endPoint, | |
| 1501 const FX_FLOAT beginRadius, | |
| 1502 const FX_FLOAT endRadius, | |
| 1503 FX_BOOL isExtendedBegin, | |
| 1504 FX_BOOL isExtendedEnd, | |
| 1505 const FX_ARGB beginArgb, | |
| 1506 const FX_ARGB endArgb) { | |
| 1507 if (_type != FX_SHADING_None) { | |
| 1508 return FX_ERR_Property_Invalid; | |
| 1509 } | |
| 1510 _type = FX_SHADING_Radial; | |
| 1511 _beginPoint = beginPoint; | |
| 1512 _endPoint = endPoint; | |
| 1513 _beginRadius = beginRadius; | |
| 1514 _endRadius = endRadius; | |
| 1515 _isExtendedBegin = isExtendedBegin; | |
| 1516 _isExtendedEnd = isExtendedEnd; | |
| 1517 _beginArgb = beginArgb; | |
| 1518 _endArgb = endArgb; | |
| 1519 return InitArgbArray(); | |
| 1520 } | |
| 1521 CFX_Shading::~CFX_Shading() { | |
| 1522 _type = FX_SHADING_None; | |
| 1523 } | |
| 1524 FX_ERR CFX_Shading::InitArgbArray() { | |
| 1525 int32_t a1, r1, g1, b1; | |
| 1526 ArgbDecode(_beginArgb, a1, r1, g1, b1); | |
| 1527 int32_t a2, r2, g2, b2; | |
| 1528 ArgbDecode(_endArgb, a2, r2, g2, b2); | |
| 1529 FX_FLOAT f = (FX_FLOAT)(FX_SHADING_Steps - 1); | |
| 1530 FX_FLOAT aScale = (FX_FLOAT)(1.0 * (a2 - a1) / f); | |
| 1531 FX_FLOAT rScale = (FX_FLOAT)(1.0 * (r2 - r1) / f); | |
| 1532 FX_FLOAT gScale = (FX_FLOAT)(1.0 * (g2 - g1) / f); | |
| 1533 FX_FLOAT bScale = (FX_FLOAT)(1.0 * (b2 - b1) / f); | |
| 1534 int32_t a3, r3, g3, b3; | |
| 1535 for (int32_t i = 0; i < FX_SHADING_Steps; i++) { | |
| 1536 a3 = (int32_t)(i * aScale); | |
| 1537 r3 = (int32_t)(i * rScale); | |
| 1538 g3 = (int32_t)(i * gScale); | |
| 1539 b3 = (int32_t)(i * bScale); | |
| 1540 _argbArray[i] = | |
| 1541 FXARGB_TODIB(FXARGB_MAKE((a1 + a3), (r1 + r3), (g1 + g3), (b1 + b3))); | |
| 1542 } | |
| 1543 return FX_ERR_Succeeded; | |
| 1544 } | |
| 1545 class CFX_Pause : public IFX_Pause { | |
| 1546 public: | |
| 1547 virtual FX_BOOL NeedToPauseNow() { return TRUE; } | |
| 1548 }; | |
| OLD | NEW |