Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(425)

Side by Side Diff: xfa/src/fxfa/app/xfa_ffwidget.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/src/fxfa/app/xfa_ffwidget.h ('k') | xfa/src/fxfa/app/xfa_ffwidgetacc.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/src/fxfa/app/xfa_ffwidget.h"
8
9 #include <algorithm>
10
11 #include "core/include/fpdfapi/fpdf_page.h"
12 #include "core/include/fxcodec/fx_codec.h"
13 #include "xfa/include/fxgraphics/fx_graphics.h"
14 #include "xfa/src/fxfa/app/xfa_ffapp.h"
15 #include "xfa/src/fxfa/app/xfa_ffdoc.h"
16 #include "xfa/src/fxfa/app/xfa_ffdocview.h"
17 #include "xfa/src/fxfa/app/xfa_ffpageview.h"
18 #include "xfa/src/fxfa/app/xfa_textlayout.h"
19
20 CXFA_FFWidget::CXFA_FFWidget(CXFA_FFPageView* pPageView,
21 CXFA_WidgetAcc* pDataAcc)
22 : CXFA_ContentLayoutItem(pDataAcc->GetNode()),
23 m_pPageView(pPageView),
24 m_pDataAcc(pDataAcc) {
25 m_rtWidget.Set(0, 0, 0, 0);
26 }
27 CXFA_FFWidget::~CXFA_FFWidget() {}
28 IXFA_PageView* CXFA_FFWidget::GetPageView() {
29 return m_pPageView;
30 }
31 void CXFA_FFWidget::SetPageView(IXFA_PageView* pPageView) {
32 m_pPageView = static_cast<CXFA_FFPageView*>(pPageView);
33 }
34 void CXFA_FFWidget::GetWidgetRect(CFX_RectF& rtWidget) {
35 if ((m_dwStatus & XFA_WIDGETSTATUS_RectCached) == 0) {
36 m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
37 GetRect(m_rtWidget);
38 }
39 rtWidget = m_rtWidget;
40 }
41 CFX_RectF CXFA_FFWidget::ReCacheWidgetRect() {
42 m_dwStatus |= XFA_WIDGETSTATUS_RectCached;
43 GetRect(m_rtWidget);
44 return m_rtWidget;
45 }
46 void CXFA_FFWidget::GetRectWithoutRotate(CFX_RectF& rtWidget) {
47 GetWidgetRect(rtWidget);
48 FX_FLOAT fValue = 0;
49 switch (m_pDataAcc->GetRotate()) {
50 case 90:
51 rtWidget.top = rtWidget.bottom();
52 fValue = rtWidget.width;
53 rtWidget.width = rtWidget.height;
54 rtWidget.height = fValue;
55 break;
56 case 180:
57 rtWidget.left = rtWidget.right();
58 rtWidget.top = rtWidget.bottom();
59 break;
60 case 270:
61 rtWidget.left = rtWidget.right();
62 fValue = rtWidget.width;
63 rtWidget.width = rtWidget.height;
64 rtWidget.height = fValue;
65 break;
66 }
67 }
68 FX_DWORD CXFA_FFWidget::GetStatus() {
69 return m_dwStatus;
70 }
71
72 void CXFA_FFWidget::ModifyStatus(FX_DWORD dwAdded, FX_DWORD dwRemoved) {
73 m_dwStatus = (m_dwStatus & ~dwRemoved) | dwAdded;
74 }
75
76 FX_BOOL CXFA_FFWidget::GetBBox(CFX_RectF& rtBox,
77 FX_DWORD dwStatus,
78 FX_BOOL bDrawFocus) {
79 if (bDrawFocus)
80 return FALSE;
81 if (m_pPageView)
82 m_pPageView->GetPageViewRect(rtBox);
83 return TRUE;
84 }
85
86 CXFA_WidgetAcc* CXFA_FFWidget::GetDataAcc() {
87 return m_pDataAcc;
88 }
89 FX_BOOL CXFA_FFWidget::GetToolTip(CFX_WideString& wsToolTip) {
90 if (CXFA_Assist assist = m_pDataAcc->GetAssist()) {
91 if (CXFA_ToolTip toolTip = assist.GetToolTip()) {
92 return toolTip.GetTip(wsToolTip);
93 }
94 }
95 return GetCaptionText(wsToolTip);
96 }
97 void CXFA_FFWidget::RenderWidget(CFX_Graphics* pGS,
98 CFX_Matrix* pMatrix,
99 FX_DWORD dwStatus,
100 int32_t iRotate) {
101 if (!IsMatchVisibleStatus(dwStatus)) {
102 return;
103 }
104 CXFA_Border border = m_pDataAcc->GetBorder();
105 if (border) {
106 CFX_RectF rtBorder;
107 GetRectWithoutRotate(rtBorder);
108 CXFA_Margin margin = border.GetMargin();
109 if (margin) {
110 XFA_RectWidthoutMargin(rtBorder, margin);
111 }
112 rtBorder.Normalize();
113 DrawBorder(pGS, border, rtBorder, pMatrix);
114 }
115 }
116 FX_BOOL CXFA_FFWidget::IsLoaded() {
117 return m_pPageView != NULL;
118 }
119 FX_BOOL CXFA_FFWidget::LoadWidget() {
120 PerformLayout();
121 return TRUE;
122 }
123 void CXFA_FFWidget::UnloadWidget() {}
124 FX_BOOL CXFA_FFWidget::PerformLayout() {
125 ReCacheWidgetRect();
126 return TRUE;
127 }
128 FX_BOOL CXFA_FFWidget::UpdateFWLData() {
129 return FALSE;
130 }
131 void CXFA_FFWidget::UpdateWidgetProperty() {}
132 void CXFA_FFWidget::DrawBorder(CFX_Graphics* pGS,
133 CXFA_Box box,
134 const CFX_RectF& rtBorder,
135 CFX_Matrix* pMatrix,
136 FX_DWORD dwFlags) {
137 XFA_DrawBox(box, pGS, rtBorder, pMatrix, dwFlags);
138 }
139 void CXFA_FFWidget::InvalidateWidget(const CFX_RectF* pRect) {
140 if (!pRect) {
141 CFX_RectF rtWidget;
142 GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
143 rtWidget.Inflate(2, 2);
144 GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, rtWidget,
145 XFA_INVALIDATE_CurrentPage);
146 } else {
147 GetDoc()->GetDocProvider()->InvalidateRect(m_pPageView, *pRect,
148 XFA_INVALIDATE_CurrentPage);
149 }
150 }
151 void CXFA_FFWidget::AddInvalidateRect(const CFX_RectF* pRect) {
152 CFX_RectF rtWidget;
153 if (pRect) {
154 rtWidget = *pRect;
155 } else {
156 GetBBox(rtWidget, XFA_WIDGETSTATUS_Focused);
157 rtWidget.Inflate(2, 2);
158 }
159 m_pDocView->AddInvalidateRect(m_pPageView, rtWidget);
160 }
161 FX_BOOL CXFA_FFWidget::GetCaptionText(CFX_WideString& wsCap) {
162 CXFA_TextLayout* pCapTextlayout = m_pDataAcc->GetCaptionTextLayout();
163 if (!pCapTextlayout) {
164 return FALSE;
165 }
166 pCapTextlayout->GetText(wsCap);
167 return TRUE;
168 }
169 FX_BOOL CXFA_FFWidget::IsFocused() {
170 return m_dwStatus & XFA_WIDGETSTATUS_Focused;
171 }
172 FX_BOOL CXFA_FFWidget::OnMouseEnter() {
173 return FALSE;
174 }
175 FX_BOOL CXFA_FFWidget::OnMouseExit() {
176 return FALSE;
177 }
178 FX_BOOL CXFA_FFWidget::OnLButtonDown(FX_DWORD dwFlags,
179 FX_FLOAT fx,
180 FX_FLOAT fy) {
181 return FALSE;
182 }
183 FX_BOOL CXFA_FFWidget::OnLButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
184 return FALSE;
185 }
186 FX_BOOL CXFA_FFWidget::OnLButtonDblClk(FX_DWORD dwFlags,
187 FX_FLOAT fx,
188 FX_FLOAT fy) {
189 return FALSE;
190 }
191 FX_BOOL CXFA_FFWidget::OnMouseMove(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
192 return FALSE;
193 }
194 FX_BOOL CXFA_FFWidget::OnMouseWheel(FX_DWORD dwFlags,
195 int16_t zDelta,
196 FX_FLOAT fx,
197 FX_FLOAT fy) {
198 return FALSE;
199 }
200 FX_BOOL CXFA_FFWidget::OnRButtonDown(FX_DWORD dwFlags,
201 FX_FLOAT fx,
202 FX_FLOAT fy) {
203 return FALSE;
204 }
205 FX_BOOL CXFA_FFWidget::OnRButtonUp(FX_DWORD dwFlags, FX_FLOAT fx, FX_FLOAT fy) {
206 return FALSE;
207 }
208 FX_BOOL CXFA_FFWidget::OnRButtonDblClk(FX_DWORD dwFlags,
209 FX_FLOAT fx,
210 FX_FLOAT fy) {
211 return FALSE;
212 }
213
214 FX_BOOL CXFA_FFWidget::OnSetFocus(CXFA_FFWidget* pOldWidget) {
215 CXFA_FFWidget* pParent = GetParent();
216 if (pParent && !pParent->IsAncestorOf(pOldWidget)) {
217 pParent->OnSetFocus(pOldWidget);
218 }
219 m_dwStatus |= XFA_WIDGETSTATUS_Focused;
220 CXFA_EventParam eParam;
221 eParam.m_eType = XFA_EVENT_Enter;
222 eParam.m_pTarget = m_pDataAcc;
223 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Enter, &eParam);
224 return TRUE;
225 }
226 FX_BOOL CXFA_FFWidget::OnKillFocus(CXFA_FFWidget* pNewWidget) {
227 m_dwStatus &= ~XFA_WIDGETSTATUS_Focused;
228 EventKillFocus();
229 if (pNewWidget) {
230 CXFA_FFWidget* pParent = GetParent();
231 if (pParent && !pParent->IsAncestorOf(pNewWidget)) {
232 pParent->OnKillFocus(pNewWidget);
233 }
234 }
235 return TRUE;
236 }
237 FX_BOOL CXFA_FFWidget::OnKeyDown(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
238 return FALSE;
239 }
240 FX_BOOL CXFA_FFWidget::OnKeyUp(FX_DWORD dwKeyCode, FX_DWORD dwFlags) {
241 return FALSE;
242 }
243 FX_BOOL CXFA_FFWidget::OnChar(FX_DWORD dwChar, FX_DWORD dwFlags) {
244 return FALSE;
245 }
246 FX_DWORD CXFA_FFWidget::OnHitTest(FX_FLOAT fx, FX_FLOAT fy) {
247 return FALSE;
248 }
249 FX_BOOL CXFA_FFWidget::OnSetCursor(FX_FLOAT fx, FX_FLOAT fy) {
250 return FALSE;
251 }
252 void CXFA_FFWidget::Rotate2Normal(FX_FLOAT& fx, FX_FLOAT& fy) {
253 CFX_Matrix mt;
254 GetRotateMatrix(mt);
255 if (mt.IsIdentity()) {
256 return;
257 }
258 CFX_Matrix mtReverse;
259 mtReverse.SetReverse(mt);
260 mtReverse.TransformPoint(fx, fy);
261 }
262 static void XFA_GetMatrix(CFX_Matrix& m,
263 int32_t iRotate,
264 int32_t at,
265 const CFX_RectF& rt) {
266 if (!iRotate) {
267 return;
268 }
269 FX_FLOAT fAnchorX, fAnchorY;
270 switch (at) {
271 case XFA_ATTRIBUTEENUM_TopLeft:
272 fAnchorX = rt.left, fAnchorY = rt.top;
273 break;
274 case XFA_ATTRIBUTEENUM_TopCenter:
275 fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.top;
276 break;
277 case XFA_ATTRIBUTEENUM_TopRight:
278 fAnchorX = rt.right(), fAnchorY = rt.top;
279 break;
280 case XFA_ATTRIBUTEENUM_MiddleLeft:
281 fAnchorX = rt.left, fAnchorY = (rt.top + rt.bottom()) / 2;
282 break;
283 case XFA_ATTRIBUTEENUM_MiddleCenter:
284 fAnchorX = (rt.left + rt.right()) / 2,
285 fAnchorY = (rt.top + rt.bottom()) / 2;
286 break;
287 case XFA_ATTRIBUTEENUM_MiddleRight:
288 fAnchorX = rt.right(), fAnchorY = (rt.top + rt.bottom()) / 2;
289 break;
290 case XFA_ATTRIBUTEENUM_BottomLeft:
291 fAnchorX = rt.left, fAnchorY = rt.bottom();
292 break;
293 case XFA_ATTRIBUTEENUM_BottomCenter:
294 fAnchorX = (rt.left + rt.right()) / 2, fAnchorY = rt.bottom();
295 break;
296 case XFA_ATTRIBUTEENUM_BottomRight:
297 fAnchorX = rt.right(), fAnchorY = rt.bottom();
298 break;
299 }
300 switch (iRotate) {
301 case 90:
302 m.a = 0, m.b = -1, m.c = 1, m.d = 0, m.e = fAnchorX - fAnchorY,
303 m.f = fAnchorX + fAnchorY;
304 break;
305 case 180:
306 m.a = -1, m.b = 0, m.c = 0, m.d = -1, m.e = fAnchorX * 2,
307 m.f = fAnchorY * 2;
308 break;
309 case 270:
310 m.a = 0, m.b = 1, m.c = -1, m.d = 0, m.e = fAnchorX + fAnchorY,
311 m.f = fAnchorY - fAnchorX;
312 break;
313 }
314 }
315 void CXFA_FFWidget::GetRotateMatrix(CFX_Matrix& mt) {
316 mt.Set(1, 0, 0, 1, 0, 0);
317 int32_t iRotate = m_pDataAcc->GetRotate();
318 if (!iRotate) {
319 return;
320 }
321 CFX_RectF rcWidget;
322 GetRectWithoutRotate(rcWidget);
323 XFA_ATTRIBUTEENUM at = XFA_ATTRIBUTEENUM_TopLeft;
324 XFA_GetMatrix(mt, iRotate, at, rcWidget);
325 }
326 FX_BOOL CXFA_FFWidget::IsLayoutRectEmpty() {
327 CFX_RectF rtLayout;
328 GetRectWithoutRotate(rtLayout);
329 return rtLayout.width < 0.1f && rtLayout.height < 0.1f;
330 }
331 CXFA_FFWidget* CXFA_FFWidget::GetParent() {
332 CXFA_Node* pParentNode =
333 m_pDataAcc->GetNode()->GetNodeItem(XFA_NODEITEM_Parent);
334 if (pParentNode) {
335 CXFA_WidgetAcc* pParentWidgetAcc =
336 (CXFA_WidgetAcc*)pParentNode->GetWidgetData();
337 if (pParentWidgetAcc) {
338 return pParentWidgetAcc->GetNextWidget(NULL);
339 }
340 }
341 return NULL;
342 }
343 FX_BOOL CXFA_FFWidget::IsAncestorOf(CXFA_FFWidget* pWidget) {
344 if (!pWidget) {
345 return FALSE;
346 }
347 CXFA_Node* pNode = m_pDataAcc->GetNode();
348 CXFA_Node* pChildNode = pWidget->GetDataAcc()->GetNode();
349 while (pChildNode) {
350 if (pChildNode == pNode) {
351 return TRUE;
352 }
353 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_Parent);
354 }
355 return FALSE;
356 }
357 FX_BOOL CXFA_FFWidget::PtInActiveRect(FX_FLOAT fx, FX_FLOAT fy) {
358 CFX_RectF rtWidget;
359 GetWidgetRect(rtWidget);
360 if (rtWidget.Contains(fx, fy)) {
361 return TRUE;
362 }
363 return FALSE;
364 }
365 CXFA_FFDocView* CXFA_FFWidget::GetDocView() {
366 return m_pDocView;
367 }
368 CXFA_FFDoc* CXFA_FFWidget::GetDoc() {
369 return (CXFA_FFDoc*)m_pDocView->GetDoc();
370 }
371 CXFA_FFApp* CXFA_FFWidget::GetApp() {
372 return GetDoc()->GetApp();
373 }
374 IXFA_AppProvider* CXFA_FFWidget::GetAppProvider() {
375 return GetApp()->GetAppProvider();
376 }
377 void CXFA_FFWidget::GetMinMaxWidth(FX_FLOAT fMinWidth, FX_FLOAT fMaxWidth) {
378 fMinWidth = fMaxWidth = 0;
379 FX_FLOAT fWidth = 0;
380 if (m_pDataAcc->GetWidth(fWidth)) {
381 fMinWidth = fMaxWidth = fWidth;
382 } else {
383 m_pDataAcc->GetMinWidth(fMinWidth);
384 m_pDataAcc->GetMaxWidth(fMaxWidth);
385 }
386 }
387 void CXFA_FFWidget::GetMinMaxHeight(FX_FLOAT fMinHeight, FX_FLOAT fMaxHeight) {
388 fMinHeight = fMaxHeight = 0;
389 FX_FLOAT fHeight = 0;
390 if (m_pDataAcc->GetHeight(fHeight)) {
391 fMinHeight = fMaxHeight = fHeight;
392 } else {
393 m_pDataAcc->GetMinHeight(fMinHeight);
394 m_pDataAcc->GetMaxHeight(fMaxHeight);
395 }
396 }
397 FX_BOOL CXFA_FFWidget::IsMatchVisibleStatus(FX_DWORD dwStatus) {
398 return m_dwStatus & XFA_WIDGETSTATUS_Visible;
399 }
400 void CXFA_FFWidget::EventKillFocus() {
401 if (m_dwStatus & XFA_WIDGETSTATUS_Access) {
402 m_dwStatus &= ~XFA_WIDGETSTATUS_Access;
403 return;
404 }
405 CXFA_EventParam eParam;
406 eParam.m_eType = XFA_EVENT_Exit;
407 eParam.m_pTarget = m_pDataAcc;
408 m_pDataAcc->ProcessEvent(XFA_ATTRIBUTEENUM_Exit, &eParam);
409 }
410 FX_BOOL CXFA_FFWidget::IsButtonDown() {
411 return (m_dwStatus & XFA_WIDGETSTATUS_ButtonDown) != 0;
412 }
413 void CXFA_FFWidget::SetButtonDown(FX_BOOL bSet) {
414 bSet ? m_dwStatus |= XFA_WIDGETSTATUS_ButtonDown
415 : m_dwStatus &= ~XFA_WIDGETSTATUS_ButtonDown;
416 }
417 int32_t XFA_StrokeTypeSetLineDash(CFX_Graphics* pGraphics,
418 int32_t iStrokeType,
419 int32_t iCapType) {
420 switch (iStrokeType) {
421 case XFA_ATTRIBUTEENUM_DashDot: {
422 FX_FLOAT dashArray[] = {4, 1, 2, 1};
423 if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
424 dashArray[1] = 2;
425 dashArray[3] = 2;
426 }
427 pGraphics->SetLineDash(0, dashArray, 4);
428 return FX_DASHSTYLE_DashDot;
429 }
430 case XFA_ATTRIBUTEENUM_DashDotDot: {
431 FX_FLOAT dashArray[] = {4, 1, 2, 1, 2, 1};
432 if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
433 dashArray[1] = 2;
434 dashArray[3] = 2;
435 dashArray[5] = 2;
436 }
437 pGraphics->SetLineDash(0, dashArray, 6);
438 return FX_DASHSTYLE_DashDotDot;
439 }
440 case XFA_ATTRIBUTEENUM_Dashed: {
441 FX_FLOAT dashArray[] = {5, 1};
442 if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
443 dashArray[1] = 2;
444 }
445 pGraphics->SetLineDash(0, dashArray, 2);
446 return FX_DASHSTYLE_Dash;
447 }
448 case XFA_ATTRIBUTEENUM_Dotted: {
449 FX_FLOAT dashArray[] = {2, 1};
450 if (iCapType != XFA_ATTRIBUTEENUM_Butt) {
451 dashArray[1] = 2;
452 }
453 pGraphics->SetLineDash(0, dashArray, 2);
454 return FX_DASHSTYLE_Dot;
455 }
456 default:
457 break;
458 }
459 pGraphics->SetLineDash(FX_DASHSTYLE_Solid);
460 return FX_DASHSTYLE_Solid;
461 }
462 CFX_GraphStateData::LineCap XFA_LineCapToFXGE(int32_t iLineCap) {
463 switch (iLineCap) {
464 case XFA_ATTRIBUTEENUM_Round:
465 return CFX_GraphStateData::LineCapRound;
466 case XFA_ATTRIBUTEENUM_Butt:
467 return CFX_GraphStateData::LineCapButt;
468 default:
469 break;
470 }
471 return CFX_GraphStateData::LineCapSquare;
472 }
473 class CXFA_ImageRenderer {
474 public:
475 CXFA_ImageRenderer();
476 ~CXFA_ImageRenderer();
477 FX_BOOL Start(CFX_RenderDevice* pDevice,
478 CFX_DIBSource* pDIBSource,
479 FX_ARGB bitmap_argb,
480 int bitmap_alpha,
481 const CFX_Matrix* pImage2Device,
482 FX_DWORD flags,
483 int blendType = FXDIB_BLEND_NORMAL);
484 FX_BOOL Continue(IFX_Pause* pPause);
485
486 protected:
487 CFX_RenderDevice* m_pDevice;
488 int m_Status;
489 CFX_Matrix m_ImageMatrix;
490 CFX_DIBSource* m_pDIBSource;
491 CFX_DIBitmap* m_pCloneConvert;
492 int m_BitmapAlpha;
493 FX_ARGB m_FillArgb;
494 FX_DWORD m_Flags;
495 CFX_ImageTransformer* m_pTransformer;
496 void* m_DeviceHandle;
497 int32_t m_BlendType;
498 FX_BOOL m_Result;
499 FX_BOOL m_bPrint;
500 FX_BOOL StartDIBSource();
501 void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
502 int left,
503 int top,
504 FX_ARGB mask_argb,
505 int bitmap_alpha,
506 int blend_mode,
507 int Transparency);
508 };
509 CXFA_ImageRenderer::CXFA_ImageRenderer() {
510 m_pDevice = NULL;
511 m_Status = 0;
512 m_pDIBSource = NULL;
513 m_pCloneConvert = NULL;
514 m_BitmapAlpha = 255;
515 m_FillArgb = 0;
516 m_Flags = 0;
517 m_pTransformer = NULL;
518 m_DeviceHandle = NULL;
519 m_BlendType = FXDIB_BLEND_NORMAL;
520 m_Result = TRUE;
521 m_bPrint = FALSE;
522 }
523 CXFA_ImageRenderer::~CXFA_ImageRenderer() {
524 if (m_pCloneConvert) {
525 delete m_pCloneConvert;
526 }
527 if (m_pTransformer) {
528 delete m_pTransformer;
529 }
530 if (m_DeviceHandle) {
531 m_pDevice->CancelDIBits(m_DeviceHandle);
532 }
533 }
534 FX_BOOL CXFA_ImageRenderer::Start(CFX_RenderDevice* pDevice,
535 CFX_DIBSource* pDIBSource,
536 FX_ARGB bitmap_argb,
537 int bitmap_alpha,
538 const CFX_Matrix* pImage2Device,
539 FX_DWORD flags,
540 int blendType) {
541 m_pDevice = pDevice;
542 m_pDIBSource = pDIBSource;
543 m_FillArgb = bitmap_argb;
544 m_BitmapAlpha = bitmap_alpha;
545 m_ImageMatrix = *pImage2Device;
546 m_Flags = flags;
547 m_BlendType = blendType;
548 return StartDIBSource();
549 }
550 FX_BOOL CXFA_ImageRenderer::StartDIBSource() {
551 if (m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb,
552 &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL,
553 m_BlendType)) {
554 if (m_DeviceHandle) {
555 m_Status = 3;
556 return TRUE;
557 }
558 return FALSE;
559 }
560 CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
561 FX_RECT image_rect = image_rect_f.GetOutterRect();
562 int dest_width = image_rect.Width();
563 int dest_height = image_rect.Height();
564 if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
565 (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) {
566 if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
567 m_Result = FALSE;
568 return FALSE;
569 }
570 CFX_DIBSource* pDib = m_pDIBSource;
571 if (m_pDIBSource->HasAlpha() &&
572 !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE) &&
573 !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
574 m_pCloneConvert = m_pDIBSource->CloneConvert(FXDIB_Rgb);
575 if (!m_pCloneConvert) {
576 m_Result = FALSE;
577 return FALSE;
578 }
579 pDib = m_pCloneConvert;
580 }
581 FX_RECT clip_box = m_pDevice->GetClipBox();
582 clip_box.Intersect(image_rect);
583 m_Status = 2;
584 m_pTransformer = new CFX_ImageTransformer;
585 m_pTransformer->Start(pDib, &m_ImageMatrix, m_Flags, &clip_box);
586 return TRUE;
587 }
588 if (m_ImageMatrix.a < 0) {
589 dest_width = -dest_width;
590 }
591 if (m_ImageMatrix.d > 0) {
592 dest_height = -dest_height;
593 }
594 int dest_left, dest_top;
595 dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
596 dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
597 if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) {
598 if (m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top, dest_width,
599 dest_height, m_Flags, NULL, m_BlendType)) {
600 return FALSE;
601 }
602 }
603 if (m_pDIBSource->IsAlphaMask()) {
604 if (m_BitmapAlpha != 255) {
605 m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
606 }
607 if (m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width,
608 dest_height, m_FillArgb, m_Flags)) {
609 return FALSE;
610 }
611 }
612 if (m_bPrint && !(m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) {
613 m_Result = FALSE;
614 return TRUE;
615 }
616 FX_RECT clip_box = m_pDevice->GetClipBox();
617 FX_RECT dest_rect = clip_box;
618 dest_rect.Intersect(image_rect);
619 FX_RECT dest_clip(
620 dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
621 dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
622 CFX_DIBitmap* pStretched =
623 m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip);
624 if (pStretched) {
625 CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb,
626 m_BitmapAlpha, m_BlendType, FALSE);
627 delete pStretched;
628 pStretched = NULL;
629 }
630 return FALSE;
631 }
632 FX_BOOL CXFA_ImageRenderer::Continue(IFX_Pause* pPause) {
633 if (m_Status == 2) {
634 if (m_pTransformer->Continue(pPause)) {
635 return TRUE;
636 }
637 CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
638 if (pBitmap == NULL) {
639 return FALSE;
640 }
641 if (pBitmap->IsAlphaMask()) {
642 if (m_BitmapAlpha != 255) {
643 m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha);
644 }
645 m_Result = m_pDevice->SetBitMask(pBitmap, m_pTransformer->m_ResultLeft,
646 m_pTransformer->m_ResultTop, m_FillArgb);
647 } else {
648 if (m_BitmapAlpha != 255) {
649 pBitmap->MultiplyAlpha(m_BitmapAlpha);
650 }
651 m_Result = m_pDevice->SetDIBits(pBitmap, m_pTransformer->m_ResultLeft,
652 m_pTransformer->m_ResultTop, m_BlendType);
653 }
654 delete pBitmap;
655 return FALSE;
656 } else if (m_Status == 3) {
657 return m_pDevice->ContinueDIBits(m_DeviceHandle, pPause);
658 }
659 return FALSE;
660 }
661 void CXFA_ImageRenderer::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap,
662 int left,
663 int top,
664 FX_ARGB mask_argb,
665 int bitmap_alpha,
666 int blend_mode,
667 int Transparency) {
668 if (pDIBitmap == NULL) {
669 return;
670 }
671 FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED;
672 FX_BOOL bGroup = Transparency & PDFTRANS_GROUP;
673 if (blend_mode == FXDIB_BLEND_NORMAL) {
674 if (!pDIBitmap->IsAlphaMask()) {
675 if (bitmap_alpha < 255) {
676 pDIBitmap->MultiplyAlpha(bitmap_alpha);
677 }
678 if (m_pDevice->SetDIBits(pDIBitmap, left, top)) {
679 return;
680 }
681 } else {
682 FX_DWORD fill_argb = (mask_argb);
683 if (bitmap_alpha < 255) {
684 ((uint8_t*)&fill_argb)[3] =
685 ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255;
686 }
687 if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) {
688 return;
689 }
690 }
691 }
692 FX_BOOL bBackAlphaRequired = blend_mode && bIsolated;
693 FX_BOOL bGetBackGround =
694 ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
695 (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
696 (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired);
697 if (bGetBackGround) {
698 if (bIsolated || !bGroup) {
699 if (pDIBitmap->IsAlphaMask()) {
700 return;
701 }
702 m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode);
703 } else {
704 FX_RECT rect(left, top, left + pDIBitmap->GetWidth(),
705 top + pDIBitmap->GetHeight());
706 rect.Intersect(m_pDevice->GetClipBox());
707 CFX_DIBitmap* pClone = NULL;
708 FX_BOOL bClone = FALSE;
709 if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) {
710 bClone = TRUE;
711 pClone = m_pDevice->GetBackDrop()->Clone(&rect);
712 CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap();
713 pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
714 pForeBitmap, rect.left, rect.top);
715 left = left >= 0 ? 0 : left;
716 top = top >= 0 ? 0 : top;
717 if (!pDIBitmap->IsAlphaMask())
718 pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(),
719 pDIBitmap, left, top, blend_mode);
720 else
721 pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(),
722 pDIBitmap, mask_argb, left, top, blend_mode);
723 } else {
724 pClone = pDIBitmap;
725 }
726 if (m_pDevice->GetBackDrop()) {
727 m_pDevice->SetDIBits(pClone, rect.left, rect.top);
728 } else {
729 if (pDIBitmap->IsAlphaMask()) {
730 return;
731 }
732 m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode);
733 }
734 if (bClone) {
735 delete pClone;
736 }
737 }
738 return;
739 }
740 if (pDIBitmap->HasAlpha() &&
741 !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE)) {
742 CFX_DIBitmap* pCloneConvert = pDIBitmap->CloneConvert(FXDIB_Rgb);
743 if (!pCloneConvert) {
744 return;
745 }
746 CXFA_ImageRenderer imageRender;
747 FX_BOOL bRet = imageRender.Start(m_pDevice, pCloneConvert, m_FillArgb,
748 m_BitmapAlpha, &m_ImageMatrix, m_Flags);
749 while (bRet) {
750 bRet = imageRender.Continue(NULL);
751 }
752 delete pCloneConvert;
753 return;
754 }
755 }
756 void XFA_DrawImage(CFX_Graphics* pGS,
757 const CFX_RectF& rtImage,
758 CFX_Matrix* pMatrix,
759 CFX_DIBitmap* pDIBitmap,
760 int32_t iAspect,
761 int32_t iImageXDpi,
762 int32_t iImageYDpi,
763 int32_t iHorzAlign,
764 int32_t iVertAlign) {
765 if (rtImage.IsEmpty()) {
766 return;
767 }
768 if (!pDIBitmap || !pDIBitmap->GetBuffer()) {
769 return;
770 }
771 FX_FLOAT fWidth =
772 XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetWidth(), (FX_FLOAT)iImageXDpi);
773 FX_FLOAT fHeight =
774 XFA_UnitPx2Pt((FX_FLOAT)pDIBitmap->GetHeight(), (FX_FLOAT)iImageYDpi);
775 CFX_RectF rtFit;
776 rtFit.Set(rtImage.left, rtImage.top, fWidth, fHeight);
777 switch (iAspect) {
778 case XFA_ATTRIBUTEENUM_Fit: {
779 FX_FLOAT f1 = rtImage.height / rtFit.height;
780 FX_FLOAT f2 = rtImage.width / rtFit.width;
781 f1 = std::min(f1, f2);
782 rtFit.height = rtFit.height * f1;
783 rtFit.width = rtFit.width * f1;
784 } break;
785 case XFA_ATTRIBUTEENUM_Actual:
786 break;
787 case XFA_ATTRIBUTEENUM_Height: {
788 FX_FLOAT f1 = rtImage.height / rtFit.height;
789 rtFit.height = rtImage.height;
790 rtFit.width = f1 * rtFit.width;
791 } break;
792 case XFA_ATTRIBUTEENUM_None:
793 rtFit.height = rtImage.height;
794 rtFit.width = rtImage.width;
795 break;
796 case XFA_ATTRIBUTEENUM_Width: {
797 FX_FLOAT f1 = rtImage.width / rtFit.width;
798 rtFit.width = rtImage.width;
799 rtFit.height = rtFit.height * f1;
800 } break;
801 }
802 if (iHorzAlign == XFA_ATTRIBUTEENUM_Center) {
803 rtFit.left += (rtImage.width - rtFit.width) / 2;
804 } else if (iHorzAlign == XFA_ATTRIBUTEENUM_Right) {
805 rtFit.left = rtImage.right() - rtFit.width;
806 }
807 if (iVertAlign == XFA_ATTRIBUTEENUM_Middle) {
808 rtFit.top += (rtImage.height - rtFit.height) / 2;
809 } else if (iVertAlign == XFA_ATTRIBUTEENUM_Bottom) {
810 rtFit.top = rtImage.bottom() - rtImage.height;
811 }
812 CFX_RenderDevice* pRenderDevice = pGS->GetRenderDevice();
813 pRenderDevice->SaveState();
814 CFX_PathData path;
815 path.AppendRect(rtImage.left, rtImage.bottom(), rtImage.right(), rtImage.top);
816 pRenderDevice->SetClip_PathFill(&path, pMatrix, FXFILL_WINDING);
817 CFX_Matrix mtImage(1, 0, 0, -1, 0, 1);
818 mtImage.Concat(rtFit.width, 0, 0, rtFit.height, rtFit.left, rtFit.top);
819 mtImage.Concat(*pMatrix);
820 CXFA_ImageRenderer imageRender;
821 FX_BOOL bRet = imageRender.Start(pRenderDevice, pDIBitmap, 0, 255, &mtImage,
822 FXDIB_INTERPOL);
823 while (bRet) {
824 bRet = imageRender.Continue(NULL);
825 }
826 pRenderDevice->RestoreState();
827 }
828
829 static const uint8_t g_inv_base64[128] = {
830 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
831 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
832 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
833 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
834 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
835 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
836 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
837 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
838 49, 50, 51, 255, 255, 255, 255, 255,
839 };
840
841 static uint8_t* XFA_RemoveBase64Whitespace(const uint8_t* pStr, int32_t iLen) {
842 uint8_t* pCP;
843 int32_t i = 0, j = 0;
844 if (iLen == 0) {
845 iLen = FXSYS_strlen((FX_CHAR*)pStr);
846 }
847 pCP = FX_Alloc(uint8_t, iLen + 1);
848 for (; i < iLen; i++) {
849 if ((pStr[i] & 128) == 0) {
850 if (g_inv_base64[pStr[i]] != 0xFF || pStr[i] == '=') {
851 pCP[j++] = pStr[i];
852 }
853 }
854 }
855 pCP[j] = '\0';
856 return pCP;
857 }
858 static int32_t XFA_Base64Decode(const FX_CHAR* pStr, uint8_t* pOutBuffer) {
859 if (pStr == NULL) {
860 return 0;
861 }
862 uint8_t* pBuffer =
863 XFA_RemoveBase64Whitespace((uint8_t*)pStr, FXSYS_strlen((FX_CHAR*)pStr));
864 if (pBuffer == NULL) {
865 return 0;
866 }
867 int32_t iLen = FXSYS_strlen((FX_CHAR*)pBuffer);
868 int32_t i = 0, j = 0;
869 FX_DWORD dwLimb = 0;
870 for (; i + 3 < iLen; i += 4) {
871 if (pBuffer[i] == '=' || pBuffer[i + 1] == '=' || pBuffer[i + 2] == '=' ||
872 pBuffer[i + 3] == '=') {
873 if (pBuffer[i] == '=' || pBuffer[i + 1] == '=') {
874 break;
875 }
876 if (pBuffer[i + 2] == '=') {
877 dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 6) |
878 ((FX_DWORD)g_inv_base64[pBuffer[i + 1]]);
879 pOutBuffer[j] = (uint8_t)(dwLimb >> 4) & 0xFF;
880 j++;
881 } else {
882 dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 12) |
883 ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 6) |
884 ((FX_DWORD)g_inv_base64[pBuffer[i + 2]]);
885 pOutBuffer[j] = (uint8_t)(dwLimb >> 10) & 0xFF;
886 pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 2) & 0xFF;
887 j += 2;
888 }
889 } else {
890 dwLimb = ((FX_DWORD)g_inv_base64[pBuffer[i]] << 18) |
891 ((FX_DWORD)g_inv_base64[pBuffer[i + 1]] << 12) |
892 ((FX_DWORD)g_inv_base64[pBuffer[i + 2]] << 6) |
893 ((FX_DWORD)g_inv_base64[pBuffer[i + 3]]);
894 pOutBuffer[j] = (uint8_t)(dwLimb >> 16) & 0xff;
895 pOutBuffer[j + 1] = (uint8_t)(dwLimb >> 8) & 0xff;
896 pOutBuffer[j + 2] = (uint8_t)(dwLimb)&0xff;
897 j += 3;
898 }
899 }
900 FX_Free(pBuffer);
901 return j;
902 }
903 static FX_CHAR g_base64_chars[] =
904 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
905 FX_CHAR* XFA_Base64Encode(const uint8_t* buf, int32_t buf_len) {
906 FX_CHAR* out = NULL;
907 int i, j;
908 FX_DWORD limb;
909 out = FX_Alloc(FX_CHAR, ((buf_len * 8 + 5) / 6) + 5);
910 for (i = 0, j = 0, limb = 0; i + 2 < buf_len; i += 3, j += 4) {
911 limb = ((FX_DWORD)buf[i] << 16) | ((FX_DWORD)buf[i + 1] << 8) |
912 ((FX_DWORD)buf[i + 2]);
913 out[j] = g_base64_chars[(limb >> 18) & 63];
914 out[j + 1] = g_base64_chars[(limb >> 12) & 63];
915 out[j + 2] = g_base64_chars[(limb >> 6) & 63];
916 out[j + 3] = g_base64_chars[(limb)&63];
917 }
918 switch (buf_len - i) {
919 case 0:
920 break;
921 case 1:
922 limb = ((FX_DWORD)buf[i]);
923 out[j++] = g_base64_chars[(limb >> 2) & 63];
924 out[j++] = g_base64_chars[(limb << 4) & 63];
925 out[j++] = '=';
926 out[j++] = '=';
927 break;
928 case 2:
929 limb = ((FX_DWORD)buf[i] << 8) | ((FX_DWORD)buf[i + 1]);
930 out[j++] = g_base64_chars[(limb >> 10) & 63];
931 out[j++] = g_base64_chars[(limb >> 4) & 63];
932 out[j++] = g_base64_chars[(limb << 2) & 63];
933 out[j++] = '=';
934 break;
935 default:
936 break;
937 }
938 out[j] = '\0';
939 return out;
940 }
941 FXCODEC_IMAGE_TYPE XFA_GetImageType(const CFX_WideStringC& wsType) {
942 CFX_WideString wsContentType(wsType);
943 wsContentType.MakeLower();
944 if (wsContentType == FX_WSTRC(L"image/jpg")) {
945 return FXCODEC_IMAGE_JPG;
946 }
947 if (wsContentType == FX_WSTRC(L"image/png")) {
948 return FXCODEC_IMAGE_PNG;
949 }
950 if (wsContentType == FX_WSTRC(L"image/gif")) {
951 return FXCODEC_IMAGE_GIF;
952 }
953 if (wsContentType == FX_WSTRC(L"image/bmp")) {
954 return FXCODEC_IMAGE_BMP;
955 }
956 if (wsContentType == FX_WSTRC(L"image/tif")) {
957 return FXCODEC_IMAGE_TIF;
958 }
959 return FXCODEC_IMAGE_UNKNOWN;
960 }
961 CFX_DIBitmap* XFA_LoadImageData(CXFA_FFDoc* pDoc,
962 CXFA_Image* pImage,
963 FX_BOOL& bNameImage,
964 int32_t& iImageXDpi,
965 int32_t& iImageYDpi) {
966 CFX_WideString wsHref;
967 pImage->GetHref(wsHref);
968 CFX_WideString wsImage;
969 pImage->GetContent(wsImage);
970 if (wsHref.IsEmpty() && wsImage.IsEmpty()) {
971 return NULL;
972 }
973 CFX_WideString wsContentType;
974 pImage->GetContentType(wsContentType);
975 FXCODEC_IMAGE_TYPE type = XFA_GetImageType(wsContentType);
976 CFX_ByteString bsContent;
977 uint8_t* pImageBuffer = NULL;
978 IFX_FileRead* pImageFileRead = NULL;
979 if (wsImage.GetLength() > 0) {
980 XFA_ATTRIBUTEENUM iEncoding =
981 (XFA_ATTRIBUTEENUM)pImage->GetTransferEncoding();
982 if (iEncoding == XFA_ATTRIBUTEENUM_Base64) {
983 CFX_ByteString bsData = wsImage.UTF8Encode();
984 int32_t iLength = bsData.GetLength();
985 pImageBuffer = FX_Alloc(uint8_t, iLength);
986 int32_t iRead = XFA_Base64Decode((const FX_CHAR*)bsData, pImageBuffer);
987 if (iRead > 0) {
988 pImageFileRead = FX_CreateMemoryStream(pImageBuffer, iRead);
989 }
990 } else {
991 bsContent = CFX_ByteString::FromUnicode(wsImage);
992 pImageFileRead = FX_CreateMemoryStream(
993 (uint8_t*)(const uint8_t*)bsContent, bsContent.GetLength());
994 }
995 } else {
996 CFX_WideString wsURL = wsHref;
997 if (wsURL.Left(7) != FX_WSTRC(L"http://") &&
998 wsURL.Left(6) != FX_WSTRC(L"ftp://")) {
999 CFX_DIBitmap* pBitmap =
1000 pDoc->GetPDFNamedImage(wsURL, iImageXDpi, iImageYDpi);
1001 if (pBitmap) {
1002 bNameImage = TRUE;
1003 return pBitmap;
1004 }
1005 }
1006 pImageFileRead = pDoc->GetDocProvider()->OpenLinkedFile(pDoc, wsURL);
1007 }
1008 if (!pImageFileRead) {
1009 FX_Free(pImageBuffer);
1010 return NULL;
1011 }
1012 bNameImage = FALSE;
1013 CFX_DIBitmap* pBitmap =
1014 XFA_LoadImageFromBuffer(pImageFileRead, type, iImageXDpi, iImageYDpi);
1015 FX_Free(pImageBuffer);
1016 pImageFileRead->Release();
1017 return pBitmap;
1018 }
1019 static FXDIB_Format XFA_GetDIBFormat(FXCODEC_IMAGE_TYPE type,
1020 int32_t iComponents,
1021 int32_t iBitsPerComponent) {
1022 FXDIB_Format dibFormat = FXDIB_Argb;
1023 switch (type) {
1024 case FXCODEC_IMAGE_BMP:
1025 case FXCODEC_IMAGE_JPG:
1026 case FXCODEC_IMAGE_TIF: {
1027 dibFormat = FXDIB_Rgb32;
1028 int32_t bpp = iComponents * iBitsPerComponent;
1029 if (bpp <= 24) {
1030 dibFormat = FXDIB_Rgb;
1031 }
1032 } break;
1033 case FXCODEC_IMAGE_PNG:
1034 default:
1035 break;
1036 }
1037 return dibFormat;
1038 }
1039 CFX_DIBitmap* XFA_LoadImageFromBuffer(IFX_FileRead* pImageFileRead,
1040 FXCODEC_IMAGE_TYPE type,
1041 int32_t& iImageXDpi,
1042 int32_t& iImageYDpi) {
1043 CFX_GEModule* pGeModule = CFX_GEModule::Get();
1044 if (!pGeModule) {
1045 return NULL;
1046 }
1047 CCodec_ModuleMgr* pCodecMgr = pGeModule->GetCodecModule();
1048 if (!pCodecMgr) {
1049 return NULL;
1050 }
1051 CFX_DIBAttribute dibAttr;
1052 CFX_DIBitmap* pBitmap = NULL;
1053 ICodec_ProgressiveDecoder* pProgressiveDecoder =
1054 pCodecMgr->CreateProgressiveDecoder();
1055 pProgressiveDecoder->LoadImageInfo(pImageFileRead, type, &dibAttr);
1056 switch (dibAttr.m_wDPIUnit) {
1057 case FXCODEC_RESUNIT_CENTIMETER:
1058 dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI * 2.54f);
1059 dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI * 2.54f);
1060 break;
1061 case FXCODEC_RESUNIT_METER:
1062 dibAttr.m_nXDPI = (int32_t)(dibAttr.m_nXDPI / (FX_FLOAT)100 * 2.54f);
1063 dibAttr.m_nYDPI = (int32_t)(dibAttr.m_nYDPI / (FX_FLOAT)100 * 2.54f);
1064 break;
1065 default:
1066 break;
1067 }
1068 iImageXDpi = dibAttr.m_nXDPI > 1 ? dibAttr.m_nXDPI : (96);
1069 iImageYDpi = dibAttr.m_nYDPI > 1 ? dibAttr.m_nYDPI : (96);
1070 if (pProgressiveDecoder->GetWidth() > 0 &&
1071 pProgressiveDecoder->GetHeight() > 0) {
1072 type = pProgressiveDecoder->GetType();
1073 int32_t iComponents = pProgressiveDecoder->GetNumComponents();
1074 int32_t iBpc = pProgressiveDecoder->GetBPC();
1075 FXDIB_Format dibFormat = XFA_GetDIBFormat(type, iComponents, iBpc);
1076 pBitmap = new CFX_DIBitmap();
1077 pBitmap->Create(pProgressiveDecoder->GetWidth(),
1078 pProgressiveDecoder->GetHeight(), dibFormat);
1079 pBitmap->Clear(0xffffffff);
1080 int32_t nFrames;
1081 if ((pProgressiveDecoder->GetFrames(nFrames) ==
1082 FXCODEC_STATUS_DECODE_READY) &&
1083 (nFrames > 0)) {
1084 pProgressiveDecoder->StartDecode(pBitmap, 0, 0, pBitmap->GetWidth(),
1085 pBitmap->GetHeight());
1086 pProgressiveDecoder->ContinueDecode();
1087 }
1088 }
1089 delete pProgressiveDecoder;
1090 return pBitmap;
1091 }
1092 void XFA_RectWidthoutMargin(CFX_RectF& rt, const CXFA_Margin& mg, FX_BOOL bUI) {
1093 if (!mg) {
1094 return;
1095 }
1096 FX_FLOAT fLeftInset, fTopInset, fRightInset, fBottomInset;
1097 mg.GetLeftInset(fLeftInset);
1098 mg.GetTopInset(fTopInset);
1099 mg.GetRightInset(fRightInset);
1100 mg.GetBottomInset(fBottomInset);
1101 rt.Deflate(fLeftInset, fTopInset, fRightInset, fBottomInset);
1102 }
1103 CXFA_FFWidget* XFA_GetWidgetFromLayoutItem(CXFA_LayoutItem* pLayoutItem) {
1104 XFA_ELEMENT iType = pLayoutItem->GetFormNode()->GetClassID();
1105 if (XFA_IsCreateWidget(iType)) {
1106 return static_cast<CXFA_FFWidget*>(pLayoutItem);
1107 }
1108 return nullptr;
1109 }
1110 FX_BOOL XFA_IsCreateWidget(XFA_ELEMENT iType) {
1111 return iType == XFA_ELEMENT_Field || iType == XFA_ELEMENT_Draw ||
1112 iType == XFA_ELEMENT_Subform || iType == XFA_ELEMENT_ExclGroup;
1113 }
1114 static void XFA_BOX_GetPath_Arc(CXFA_Box box,
1115 CFX_RectF rtDraw,
1116 CFX_Path& fillPath,
1117 FX_DWORD dwFlags) {
1118 FX_FLOAT a, b;
1119 a = rtDraw.width / 2.0f;
1120 b = rtDraw.height / 2.0f;
1121 if (box.IsCircular() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
1122 a = b = std::min(a, b);
1123 }
1124 CFX_PointF center = rtDraw.Center();
1125 rtDraw.left = center.x - a;
1126 rtDraw.top = center.y - b;
1127 rtDraw.width = a + a;
1128 rtDraw.height = b + b;
1129 FX_FLOAT startAngle = 0, sweepAngle = 360;
1130 FX_BOOL bStart = box.GetStartAngle(startAngle);
1131 FX_BOOL bEnd = box.GetSweepAngle(sweepAngle);
1132 if (!bStart && !bEnd) {
1133 fillPath.AddEllipse(rtDraw);
1134 return;
1135 }
1136 startAngle = -startAngle * FX_PI / 180.0f;
1137 sweepAngle = -sweepAngle * FX_PI / 180.0f;
1138 fillPath.AddArc(rtDraw.left, rtDraw.top, rtDraw.width, rtDraw.height,
1139 startAngle, sweepAngle);
1140 }
1141 static void XFA_BOX_GetPath(CXFA_Box box,
1142 const CXFA_StrokeArray& strokes,
1143 CFX_RectF rtWidget,
1144 CFX_Path& path,
1145 int32_t nIndex,
1146 FX_BOOL bStart,
1147 FX_BOOL bCorner) {
1148 FXSYS_assert(nIndex >= 0 && nIndex < 8);
1149 FX_BOOL bInverted, bRound;
1150 FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny, offsetY, offsetX,
1151 offsetEX, offsetEY;
1152 CFX_PointF cpStart, cp, cp1, cp2;
1153 CFX_RectF rtRadius;
1154 int32_t n = (nIndex & 1) ? nIndex - 1 : nIndex;
1155 CXFA_Corner corner1(strokes[n].GetNode());
1156 CXFA_Corner corner2(strokes[(n + 2) % 8].GetNode());
1157 fRadius1 = bCorner ? corner1.GetRadius() : 0;
1158 fRadius2 = bCorner ? corner2.GetRadius() : 0;
1159 bInverted = corner1.IsInverted();
1160 offsetY = 0.0f;
1161 offsetX = 0.0f;
1162 bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
1163 FX_FLOAT halfAfter = 0.0f;
1164 FX_FLOAT halfBefore = 0.0f;
1165 CXFA_Stroke stroke = strokes[nIndex];
1166 if (stroke.IsCorner()) {
1167 CXFA_Stroke edgeBefore = strokes[(nIndex + 1 * 8 - 1) % 8];
1168 CXFA_Stroke edgeAfter = strokes[nIndex + 1];
1169 if (stroke.IsInverted()) {
1170 if (!stroke.SameStyles(edgeBefore)) {
1171 halfBefore = edgeBefore.GetThickness() / 2;
1172 }
1173 if (!stroke.SameStyles(edgeAfter)) {
1174 halfAfter = edgeAfter.GetThickness() / 2;
1175 }
1176 }
1177 } else {
1178 CXFA_Stroke edgeBefore = strokes[(nIndex + 8 - 2) % 8];
1179 CXFA_Stroke edgeAfter = strokes[(nIndex + 2) % 8];
1180 if (!bRound && !bInverted) {
1181 { halfBefore = edgeBefore.GetThickness() / 2; }
1182 { halfAfter = edgeAfter.GetThickness() / 2; }
1183 }
1184 }
1185 offsetEX = 0.0f;
1186 offsetEY = 0.0f;
1187 if (bRound) {
1188 sy = FX_PI / 2;
1189 }
1190 switch (nIndex) {
1191 case 0:
1192 case 1:
1193 cp1 = rtWidget.TopLeft();
1194 cp2 = rtWidget.TopRight();
1195 if (nIndex == 0) {
1196 cpStart.x = cp1.x - halfBefore;
1197 cpStart.y = cp1.y + fRadius1, offsetY = -halfAfter;
1198 } else {
1199 cpStart.x = cp1.x + fRadius1 - halfBefore, cpStart.y = cp1.y,
1200 offsetEX = halfAfter;
1201 }
1202 vx = 1, vy = 1;
1203 nx = -1, ny = 0;
1204 if (bRound) {
1205 sx = bInverted ? FX_PI / 2 : FX_PI;
1206 } else {
1207 sx = 1, sy = 0;
1208 }
1209 break;
1210 case 2:
1211 case 3:
1212 cp1 = rtWidget.TopRight();
1213 cp2 = rtWidget.BottomRight();
1214 if (nIndex == 2) {
1215 cpStart.x = cp1.x - fRadius1, cpStart.y = cp1.y - halfBefore,
1216 offsetX = halfAfter;
1217 } else {
1218 cpStart.x = cp1.x, cpStart.y = cp1.y + fRadius1 - halfBefore,
1219 offsetEY = halfAfter;
1220 }
1221 vx = -1, vy = 1;
1222 nx = 0, ny = -1;
1223 if (bRound) {
1224 sx = bInverted ? FX_PI : FX_PI * 3 / 2;
1225 } else {
1226 sx = 0, sy = 1;
1227 }
1228 break;
1229 case 4:
1230 case 5:
1231 cp1 = rtWidget.BottomRight();
1232 cp2 = rtWidget.BottomLeft();
1233 if (nIndex == 4) {
1234 cpStart.x = cp1.x + halfBefore, cpStart.y = cp1.y - fRadius1,
1235 offsetY = halfAfter;
1236 } else {
1237 cpStart.x = cp1.x - fRadius1 + halfBefore, cpStart.y = cp1.y,
1238 offsetEX = -halfAfter;
1239 }
1240 vx = -1, vy = -1;
1241 nx = 1, ny = 0;
1242 if (bRound) {
1243 sx = bInverted ? FX_PI * 3 / 2 : 0;
1244 } else {
1245 sx = -1, sy = 0;
1246 }
1247 break;
1248 case 6:
1249 case 7:
1250 cp1 = rtWidget.BottomLeft();
1251 cp2 = rtWidget.TopLeft();
1252 if (nIndex == 6) {
1253 cpStart.x = cp1.x + fRadius1, cpStart.y = cp1.y + halfBefore,
1254 offsetX = -halfAfter;
1255 } else {
1256 cpStart.x = cp1.x, cpStart.y = cp1.y - fRadius1 + halfBefore,
1257 offsetEY = -halfAfter;
1258 }
1259 vx = 1, vy = -1;
1260 nx = 0, ny = 1;
1261 if (bRound) {
1262 sx = bInverted ? 0 : FX_PI / 2;
1263 } else {
1264 sx = 0, sy = -1;
1265 }
1266 break;
1267 }
1268 if (bStart) {
1269 path.MoveTo(cpStart.x, cpStart.y);
1270 }
1271 if (nIndex & 1) {
1272 path.LineTo(cp2.x + fRadius2 * nx + offsetEX,
1273 cp2.y + fRadius2 * ny + offsetEY);
1274 return;
1275 }
1276 if (bRound) {
1277 if (fRadius1 < 0) {
1278 sx -= FX_PI;
1279 }
1280 if (bInverted) {
1281 sy *= -1;
1282 }
1283 rtRadius.Set(cp1.x + offsetX * 2, cp1.y + offsetY * 2,
1284 fRadius1 * 2 * vx - offsetX * 2,
1285 fRadius1 * 2 * vy - offsetY * 2);
1286 rtRadius.Normalize();
1287 if (bInverted) {
1288 rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
1289 }
1290 path.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width, rtRadius.height, sx,
1291 sy);
1292 } else {
1293 if (bInverted) {
1294 cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
1295 } else {
1296 cp = cp1;
1297 }
1298 path.LineTo(cp.x, cp.y);
1299 path.LineTo(cp1.x + fRadius1 * sx + offsetX,
1300 cp1.y + fRadius1 * sy + offsetY);
1301 }
1302 }
1303 static void XFA_BOX_GetFillPath(CXFA_Box box,
1304 const CXFA_StrokeArray& strokes,
1305 CFX_RectF rtWidget,
1306 CFX_Path& fillPath,
1307 FX_WORD dwFlags) {
1308 if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
1309 CXFA_Edge edge = box.GetEdge(0);
1310 FX_FLOAT fThickness = edge.GetThickness();
1311 if (fThickness < 0) {
1312 fThickness = 0;
1313 }
1314 FX_FLOAT fHalf = fThickness / 2;
1315 int32_t iHand = box.GetHand();
1316 if (iHand == XFA_ATTRIBUTEENUM_Left) {
1317 rtWidget.Inflate(fHalf, fHalf);
1318 } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
1319 rtWidget.Deflate(fHalf, fHalf);
1320 }
1321 XFA_BOX_GetPath_Arc(box, rtWidget, fillPath, dwFlags);
1322 return;
1323 }
1324 FX_BOOL bSameStyles = TRUE;
1325 int32_t i;
1326 CXFA_Stroke stroke1 = strokes[0];
1327 for (i = 1; i < 8; i++) {
1328 CXFA_Stroke stroke2 = strokes[i];
1329 if (!stroke1.SameStyles(stroke2)) {
1330 bSameStyles = FALSE;
1331 break;
1332 }
1333 stroke1 = stroke2;
1334 }
1335 if (bSameStyles) {
1336 stroke1 = strokes[0];
1337 for (i = 2; i < 8; i += 2) {
1338 CXFA_Stroke stroke2 = strokes[i];
1339 if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
1340 XFA_STROKE_SAMESTYLE_Corner)) {
1341 bSameStyles = FALSE;
1342 break;
1343 }
1344 stroke1 = stroke2;
1345 }
1346 if (bSameStyles) {
1347 stroke1 = strokes[0];
1348 if (stroke1.IsInverted()) {
1349 bSameStyles = FALSE;
1350 }
1351 if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
1352 bSameStyles = FALSE;
1353 }
1354 }
1355 }
1356 if (bSameStyles) {
1357 fillPath.AddRectangle(rtWidget.left, rtWidget.top, rtWidget.width,
1358 rtWidget.height);
1359 return;
1360 }
1361 FX_BOOL bInverted, bRound;
1362 FX_FLOAT fRadius1, fRadius2, sx, sy, vx, vy, nx, ny;
1363 CFX_PointF cp, cp1, cp2;
1364 CFX_RectF rtRadius;
1365 for (int32_t i = 0; i < 8; i += 2) {
1366 CXFA_Corner corner1(strokes[i].GetNode());
1367 CXFA_Corner corner2(strokes[(i + 2) % 8].GetNode());
1368 fRadius1 = corner1.GetRadius();
1369 fRadius2 = corner2.GetRadius();
1370 bInverted = corner1.IsInverted();
1371 bRound = corner1.GetJoinType() == XFA_ATTRIBUTEENUM_Round;
1372 if (bRound) {
1373 sy = FX_PI / 2;
1374 }
1375 switch (i) {
1376 case 0:
1377 cp1 = rtWidget.TopLeft();
1378 cp2 = rtWidget.TopRight();
1379 vx = 1, vy = 1;
1380 nx = -1, ny = 0;
1381 if (bRound) {
1382 sx = bInverted ? FX_PI / 2 : FX_PI;
1383 } else {
1384 sx = 1, sy = 0;
1385 }
1386 break;
1387 case 2:
1388 cp1 = rtWidget.TopRight();
1389 cp2 = rtWidget.BottomRight();
1390 vx = -1, vy = 1;
1391 nx = 0, ny = -1;
1392 if (bRound) {
1393 sx = bInverted ? FX_PI : FX_PI * 3 / 2;
1394 } else {
1395 sx = 0, sy = 1;
1396 }
1397 break;
1398 case 4:
1399 cp1 = rtWidget.BottomRight();
1400 cp2 = rtWidget.BottomLeft();
1401 vx = -1, vy = -1;
1402 nx = 1, ny = 0;
1403 if (bRound) {
1404 sx = bInverted ? FX_PI * 3 / 2 : 0;
1405 } else {
1406 sx = -1, sy = 0;
1407 }
1408 break;
1409 case 6:
1410 cp1 = rtWidget.BottomLeft();
1411 cp2 = rtWidget.TopLeft();
1412 vx = 1, vy = -1;
1413 nx = 0, ny = 1;
1414 if (bRound) {
1415 sx = bInverted ? 0 : FX_PI / 2;
1416 } else {
1417 sx = 0, sy = -1;
1418 }
1419 break;
1420 }
1421 if (i == 0) {
1422 fillPath.MoveTo(cp1.x, cp1.y + fRadius1);
1423 }
1424 if (bRound) {
1425 if (fRadius1 < 0) {
1426 sx -= FX_PI;
1427 }
1428 if (bInverted) {
1429 sy *= -1;
1430 }
1431 rtRadius.Set(cp1.x, cp1.y, fRadius1 * 2 * vx, fRadius1 * 2 * vy);
1432 rtRadius.Normalize();
1433 if (bInverted) {
1434 rtRadius.Offset(-fRadius1 * vx, -fRadius1 * vy);
1435 }
1436 fillPath.ArcTo(rtRadius.left, rtRadius.top, rtRadius.width,
1437 rtRadius.height, sx, sy);
1438 } else {
1439 if (bInverted) {
1440 cp.x = cp1.x + fRadius1 * vx, cp.y = cp1.y + fRadius1 * vy;
1441 } else {
1442 cp = cp1;
1443 }
1444 fillPath.LineTo(cp.x, cp.y);
1445 fillPath.LineTo(cp1.x + fRadius1 * sx, cp1.y + fRadius1 * sy);
1446 }
1447 fillPath.LineTo(cp2.x + fRadius2 * nx, cp2.y + fRadius2 * ny);
1448 }
1449 }
1450 static void XFA_BOX_Fill_Radial(CXFA_Box box,
1451 CFX_Graphics* pGS,
1452 CFX_Path& fillPath,
1453 CFX_RectF rtFill,
1454 CFX_Matrix* pMatrix) {
1455 CXFA_Fill fill = box.GetFill();
1456 FX_ARGB crStart, crEnd;
1457 crStart = fill.GetColor();
1458 int32_t iType = fill.GetRadial(crEnd);
1459 CFX_Shading shading;
1460 if (iType != XFA_ATTRIBUTEENUM_ToEdge) {
1461 FX_ARGB temp = crEnd;
1462 crEnd = crStart;
1463 crStart = temp;
1464 }
1465 shading.CreateRadial(rtFill.Center(), rtFill.Center(), 0,
1466 FXSYS_sqrt(rtFill.Width() * rtFill.Width() +
1467 rtFill.Height() * rtFill.Height()) /
1468 2,
1469 TRUE, TRUE, crStart, crEnd);
1470 CFX_Color cr(&shading);
1471 pGS->SetFillColor(&cr);
1472 pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
1473 }
1474 static void XFA_BOX_Fill_Pattern(CXFA_Box box,
1475 CFX_Graphics* pGS,
1476 CFX_Path& fillPath,
1477 CFX_RectF rtFill,
1478 CFX_Matrix* pMatrix) {
1479 CXFA_Fill fill = box.GetFill();
1480 FX_ARGB crStart, crEnd;
1481 crStart = fill.GetColor();
1482 int32_t iType = fill.GetPattern(crEnd);
1483 int32_t iHatch = FX_HATCHSTYLE_Cross;
1484 switch (iType) {
1485 case XFA_ATTRIBUTEENUM_CrossDiagonal:
1486 iHatch = FX_HATCHSTYLE_DiagonalCross;
1487 break;
1488 case XFA_ATTRIBUTEENUM_DiagonalLeft:
1489 iHatch = FX_HATCHSTYLE_ForwardDiagonal;
1490 break;
1491 case XFA_ATTRIBUTEENUM_DiagonalRight:
1492 iHatch = FX_HATCHSTYLE_BackwardDiagonal;
1493 break;
1494 case XFA_ATTRIBUTEENUM_Horizontal:
1495 iHatch = FX_HATCHSTYLE_Horizontal;
1496 break;
1497 case XFA_ATTRIBUTEENUM_Vertical:
1498 iHatch = FX_HATCHSTYLE_Vertical;
1499 break;
1500 default:
1501 break;
1502 }
1503 CFX_Pattern pattern;
1504 pattern.Create(iHatch, crEnd, crStart);
1505 CFX_Color cr(&pattern);
1506 pGS->SetFillColor(&cr);
1507 pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
1508 }
1509 static void XFA_BOX_Fill_Linear(CXFA_Box box,
1510 CFX_Graphics* pGS,
1511 CFX_Path& fillPath,
1512 CFX_RectF rtFill,
1513 CFX_Matrix* pMatrix) {
1514 CXFA_Fill fill = box.GetFill();
1515 FX_ARGB crStart = fill.GetColor();
1516 FX_ARGB crEnd;
1517 int32_t iType = fill.GetLinear(crEnd);
1518 CFX_PointF ptStart;
1519 CFX_PointF ptEnd;
1520 switch (iType) {
1521 case XFA_ATTRIBUTEENUM_ToRight:
1522 ptStart = CFX_PointF(rtFill.left, rtFill.top);
1523 ptEnd = CFX_PointF(rtFill.right(), rtFill.top);
1524 break;
1525 case XFA_ATTRIBUTEENUM_ToBottom:
1526 ptStart = CFX_PointF(rtFill.left, rtFill.top);
1527 ptEnd = CFX_PointF(rtFill.left, rtFill.bottom());
1528 break;
1529 case XFA_ATTRIBUTEENUM_ToLeft:
1530 ptStart = CFX_PointF(rtFill.right(), rtFill.top);
1531 ptEnd = CFX_PointF(rtFill.left, rtFill.top);
1532 break;
1533 case XFA_ATTRIBUTEENUM_ToTop:
1534 ptStart = CFX_PointF(rtFill.left, rtFill.bottom());
1535 ptEnd = CFX_PointF(rtFill.left, rtFill.top);
1536 break;
1537 default:
1538 break;
1539 }
1540 CFX_Shading shading;
1541 shading.CreateAxial(ptStart, ptEnd, FALSE, FALSE, crStart, crEnd);
1542 CFX_Color cr(&shading);
1543 pGS->SetFillColor(&cr);
1544 pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
1545 }
1546 static void XFA_BOX_Fill(CXFA_Box box,
1547 const CXFA_StrokeArray& strokes,
1548 CFX_Graphics* pGS,
1549 const CFX_RectF& rtWidget,
1550 CFX_Matrix* pMatrix,
1551 FX_DWORD dwFlags) {
1552 CXFA_Fill fill = box.GetFill();
1553 if (!fill || fill.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
1554 return;
1555 }
1556 pGS->SaveGraphState();
1557 CFX_Path fillPath;
1558 fillPath.Create();
1559 XFA_BOX_GetFillPath(box, strokes, rtWidget, fillPath,
1560 (dwFlags & XFA_DRAWBOX_ForceRound) != 0);
1561 fillPath.Close();
1562 int32_t eType = fill.GetFillType();
1563 switch (eType) {
1564 case XFA_ELEMENT_Radial:
1565 XFA_BOX_Fill_Radial(box, pGS, fillPath, rtWidget, pMatrix);
1566 break;
1567 case XFA_ELEMENT_Pattern:
1568 XFA_BOX_Fill_Pattern(box, pGS, fillPath, rtWidget, pMatrix);
1569 break;
1570 case XFA_ELEMENT_Linear:
1571 XFA_BOX_Fill_Linear(box, pGS, fillPath, rtWidget, pMatrix);
1572 break;
1573 default: {
1574 FX_ARGB cr;
1575 if (eType == XFA_ELEMENT_Stipple) {
1576 int32_t iRate = fill.GetStipple(cr);
1577 if (iRate == 0) {
1578 iRate = 100;
1579 }
1580 int32_t a = 0;
1581 FX_COLORREF rgb;
1582 ArgbDecode(cr, a, rgb);
1583 cr = ArgbEncode(iRate * a / 100, rgb);
1584 } else {
1585 cr = fill.GetColor();
1586 }
1587 CFX_Color fillColor(cr);
1588 pGS->SetFillColor(&fillColor);
1589 pGS->FillPath(&fillPath, FXFILL_WINDING, pMatrix);
1590 } break;
1591 }
1592 pGS->RestoreGraphState();
1593 }
1594 static void XFA_BOX_StrokePath(CXFA_Stroke stroke,
1595 CFX_Path* pPath,
1596 CFX_Graphics* pGS,
1597 CFX_Matrix* pMatrix) {
1598 if (!stroke || !stroke.IsVisible()) {
1599 return;
1600 }
1601 FX_FLOAT fThickness = stroke.GetThickness();
1602 if (fThickness < 0.001f) {
1603 return;
1604 }
1605 pGS->SaveGraphState();
1606 if (stroke.IsCorner() && fThickness > 2 * stroke.GetRadius()) {
1607 fThickness = 2 * stroke.GetRadius();
1608 }
1609 pGS->SetLineWidth(fThickness, TRUE);
1610 pGS->SetLineCap(CFX_GraphStateData::LineCapButt);
1611 XFA_StrokeTypeSetLineDash(pGS, stroke.GetStrokeType(),
1612 XFA_ATTRIBUTEENUM_Butt);
1613 CFX_Color fxColor(stroke.GetColor());
1614 pGS->SetStrokeColor(&fxColor);
1615 pGS->StrokePath(pPath, pMatrix);
1616 pGS->RestoreGraphState();
1617 }
1618 static void XFA_BOX_StrokeArc(CXFA_Box box,
1619 CFX_Graphics* pGS,
1620 CFX_RectF rtWidget,
1621 CFX_Matrix* pMatrix,
1622 FX_DWORD dwFlags) {
1623 CXFA_Edge edge = box.GetEdge(0);
1624 if (!edge || !edge.IsVisible()) {
1625 return;
1626 }
1627 FX_BOOL bVisible = FALSE;
1628 FX_FLOAT fThickness = 0;
1629 int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
1630 if (i3DType) {
1631 if (bVisible && fThickness >= 0.001f) {
1632 dwFlags |= XFA_DRAWBOX_Lowered3D;
1633 }
1634 }
1635 FX_FLOAT fHalf = edge.GetThickness() / 2;
1636 if (fHalf < 0) {
1637 fHalf = 0;
1638 }
1639 int32_t iHand = box.GetHand();
1640 if (iHand == XFA_ATTRIBUTEENUM_Left) {
1641 rtWidget.Inflate(fHalf, fHalf);
1642 } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
1643 rtWidget.Deflate(fHalf, fHalf);
1644 }
1645 if ((dwFlags & XFA_DRAWBOX_ForceRound) == 0 ||
1646 (dwFlags & XFA_DRAWBOX_Lowered3D) == 0) {
1647 if (fHalf < 0.001f) {
1648 return;
1649 }
1650 CFX_Path arcPath;
1651 arcPath.Create();
1652 XFA_BOX_GetPath_Arc(box, rtWidget, arcPath, dwFlags);
1653 XFA_BOX_StrokePath(edge, &arcPath, pGS, pMatrix);
1654 return;
1655 }
1656 pGS->SaveGraphState();
1657 pGS->SetLineWidth(fHalf);
1658 FX_FLOAT a, b;
1659 a = rtWidget.width / 2.0f;
1660 b = rtWidget.height / 2.0f;
1661 if (dwFlags & XFA_DRAWBOX_ForceRound) {
1662 a = b = std::min(a, b);
1663 }
1664 CFX_PointF center = rtWidget.Center();
1665 rtWidget.left = center.x - a;
1666 rtWidget.top = center.y - b;
1667 rtWidget.width = a + a;
1668 rtWidget.height = b + b;
1669 FX_FLOAT startAngle = 0, sweepAngle = 360;
1670 startAngle = startAngle * FX_PI / 180.0f;
1671 sweepAngle = -sweepAngle * FX_PI / 180.0f;
1672 CFX_Path arcPath;
1673 arcPath.Create();
1674 arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
1675 3.0f * FX_PI / 4.0f, FX_PI);
1676 CFX_Color cr(0xFF808080);
1677 pGS->SetStrokeColor(&cr);
1678 pGS->StrokePath(&arcPath, pMatrix);
1679 arcPath.Clear();
1680 arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
1681 -1.0f * FX_PI / 4.0f, FX_PI);
1682 cr.Set(0xFFFFFFFF);
1683 pGS->SetStrokeColor(&cr);
1684 pGS->StrokePath(&arcPath, pMatrix);
1685 rtWidget.Deflate(fHalf, fHalf);
1686 arcPath.Clear();
1687 arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
1688 3.0f * FX_PI / 4.0f, FX_PI);
1689 cr.Set(0xFF404040);
1690 pGS->SetStrokeColor(&cr);
1691 pGS->StrokePath(&arcPath, pMatrix);
1692 arcPath.Clear();
1693 arcPath.AddArc(rtWidget.left, rtWidget.top, rtWidget.width, rtWidget.height,
1694 -1.0f * FX_PI / 4.0f, FX_PI);
1695 cr.Set(0xFFC0C0C0);
1696 pGS->SetStrokeColor(&cr);
1697 pGS->StrokePath(&arcPath, pMatrix);
1698 pGS->RestoreGraphState();
1699 }
1700 static void XFA_Draw3DRect(CFX_Graphics* pGraphic,
1701 const CFX_RectF& rt,
1702 FX_FLOAT fLineWidth,
1703 CFX_Matrix* pMatrix,
1704 FX_ARGB argbTopLeft,
1705 FX_ARGB argbBottomRight) {
1706 CFX_Color crLT(argbTopLeft);
1707 pGraphic->SetFillColor(&crLT);
1708 FX_FLOAT fBottom = rt.bottom();
1709 FX_FLOAT fRight = rt.right();
1710 CFX_Path pathLT;
1711 pathLT.Create();
1712 pathLT.MoveTo(rt.left, fBottom);
1713 pathLT.LineTo(rt.left, rt.top);
1714 pathLT.LineTo(fRight, rt.top);
1715 pathLT.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
1716 pathLT.LineTo(rt.left + fLineWidth, rt.top + fLineWidth);
1717 pathLT.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
1718 pathLT.LineTo(rt.left, fBottom);
1719 pGraphic->FillPath(&pathLT, FXFILL_WINDING, pMatrix);
1720 CFX_Color crRB(argbBottomRight);
1721 pGraphic->SetFillColor(&crRB);
1722 CFX_Path pathRB;
1723 pathRB.Create();
1724 pathRB.MoveTo(fRight, rt.top);
1725 pathRB.LineTo(fRight, fBottom);
1726 pathRB.LineTo(rt.left, fBottom);
1727 pathRB.LineTo(rt.left + fLineWidth, fBottom - fLineWidth);
1728 pathRB.LineTo(fRight - fLineWidth, fBottom - fLineWidth);
1729 pathRB.LineTo(fRight - fLineWidth, rt.top + fLineWidth);
1730 pathRB.LineTo(fRight, rt.top);
1731 pGraphic->FillPath(&pathRB, FXFILL_WINDING, pMatrix);
1732 }
1733 static void XFA_BOX_Stroke_3DRect_Lowered(CFX_Graphics* pGS,
1734 CFX_RectF rt,
1735 FX_FLOAT fThickness,
1736 CFX_Matrix* pMatrix) {
1737 FX_FLOAT fHalfWidth = fThickness / 2.0f;
1738 CFX_RectF rtInner(rt);
1739 rtInner.Deflate(fHalfWidth, fHalfWidth);
1740 CFX_Color cr(0xFF000000);
1741 pGS->SetFillColor(&cr);
1742 CFX_Path path;
1743 path.Create();
1744 path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
1745 path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
1746 pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
1747 XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF808080, 0xFFC0C0C0);
1748 }
1749 static void XFA_BOX_Stroke_3DRect_Raised(CFX_Graphics* pGS,
1750 CFX_RectF rt,
1751 FX_FLOAT fThickness,
1752 CFX_Matrix* pMatrix) {
1753 FX_FLOAT fHalfWidth = fThickness / 2.0f;
1754 CFX_RectF rtInner(rt);
1755 rtInner.Deflate(fHalfWidth, fHalfWidth);
1756 CFX_Color cr(0xFF000000);
1757 pGS->SetFillColor(&cr);
1758 CFX_Path path;
1759 path.Create();
1760 path.AddRectangle(rt.left, rt.top, rt.width, rt.height);
1761 path.AddRectangle(rtInner.left, rtInner.top, rtInner.width, rtInner.height);
1762 pGS->FillPath(&path, FXFILL_ALTERNATE, pMatrix);
1763 XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
1764 }
1765 static void XFA_BOX_Stroke_3DRect_Etched(CFX_Graphics* pGS,
1766 CFX_RectF rt,
1767 FX_FLOAT fThickness,
1768 CFX_Matrix* pMatrix) {
1769 FX_FLOAT fHalfWidth = fThickness / 2.0f;
1770 XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFFFFFFFF);
1771 CFX_RectF rtInner(rt);
1772 rtInner.Deflate(fHalfWidth, fHalfWidth);
1773 XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFFFFFFFF, 0xFF808080);
1774 }
1775 static void XFA_BOX_Stroke_3DRect_Embossed(CFX_Graphics* pGS,
1776 CFX_RectF rt,
1777 FX_FLOAT fThickness,
1778 CFX_Matrix* pMatrix) {
1779 FX_FLOAT fHalfWidth = fThickness / 2.0f;
1780 XFA_Draw3DRect(pGS, rt, fThickness, pMatrix, 0xFF808080, 0xFF000000);
1781 CFX_RectF rtInner(rt);
1782 rtInner.Deflate(fHalfWidth, fHalfWidth);
1783 XFA_Draw3DRect(pGS, rtInner, fHalfWidth, pMatrix, 0xFF000000, 0xFF808080);
1784 }
1785 static void XFA_BOX_Stroke_Rect(CXFA_Box box,
1786 const CXFA_StrokeArray& strokes,
1787 CFX_Graphics* pGS,
1788 CFX_RectF rtWidget,
1789 CFX_Matrix* pMatrix) {
1790 FX_BOOL bVisible = FALSE;
1791 FX_FLOAT fThickness = 0;
1792 int32_t i3DType = box.Get3DStyle(bVisible, fThickness);
1793 if (i3DType) {
1794 if (!bVisible || fThickness < 0.001f) {
1795 return;
1796 }
1797 switch (i3DType) {
1798 case XFA_ATTRIBUTEENUM_Lowered:
1799 XFA_BOX_Stroke_3DRect_Lowered(pGS, rtWidget, fThickness, pMatrix);
1800 break;
1801 case XFA_ATTRIBUTEENUM_Raised:
1802 XFA_BOX_Stroke_3DRect_Raised(pGS, rtWidget, fThickness, pMatrix);
1803 break;
1804 case XFA_ATTRIBUTEENUM_Etched:
1805 XFA_BOX_Stroke_3DRect_Etched(pGS, rtWidget, fThickness, pMatrix);
1806 break;
1807 case XFA_ATTRIBUTEENUM_Embossed:
1808 XFA_BOX_Stroke_3DRect_Embossed(pGS, rtWidget, fThickness, pMatrix);
1809 break;
1810 }
1811 return;
1812 }
1813 FX_BOOL bClose = FALSE;
1814 FX_BOOL bSameStyles = TRUE;
1815 int32_t i;
1816 CXFA_Stroke stroke1 = strokes[0];
1817 for (i = 1; i < 8; i++) {
1818 CXFA_Stroke stroke2 = strokes[i];
1819 if (!stroke1.SameStyles(stroke2)) {
1820 bSameStyles = FALSE;
1821 break;
1822 }
1823 stroke1 = stroke2;
1824 }
1825 if (bSameStyles) {
1826 stroke1 = strokes[0];
1827 bClose = TRUE;
1828 for (i = 2; i < 8; i += 2) {
1829 CXFA_Stroke stroke2 = strokes[i];
1830 if (!stroke1.SameStyles(stroke2, XFA_STROKE_SAMESTYLE_NoPresence |
1831 XFA_STROKE_SAMESTYLE_Corner)) {
1832 bSameStyles = FALSE;
1833 break;
1834 }
1835 stroke1 = stroke2;
1836 }
1837 if (bSameStyles) {
1838 stroke1 = strokes[0];
1839 if (stroke1.IsInverted()) {
1840 bSameStyles = FALSE;
1841 }
1842 if (stroke1.GetJoinType() != XFA_ATTRIBUTEENUM_Square) {
1843 bSameStyles = FALSE;
1844 }
1845 }
1846 }
1847 FX_BOOL bStart = TRUE;
1848 CFX_Path path;
1849 path.Create();
1850 for (i = 0; i < 8; i++) {
1851 CXFA_Stroke stroke1 = strokes[i];
1852 if ((i % 1) == 0 && stroke1.GetRadius() < 0) {
1853 FX_BOOL bEmpty = path.IsEmpty();
1854 if (!bEmpty) {
1855 XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
1856 path.Clear();
1857 }
1858 bStart = TRUE;
1859 continue;
1860 }
1861 XFA_BOX_GetPath(box, strokes, rtWidget, path, i, bStart, !bSameStyles);
1862 CXFA_Stroke stroke2 = strokes[(i + 1) % 8];
1863 bStart = !stroke1.SameStyles(stroke2);
1864 if (bStart) {
1865 XFA_BOX_StrokePath(stroke1, &path, pGS, pMatrix);
1866 path.Clear();
1867 }
1868 }
1869 FX_BOOL bEmpty = path.IsEmpty();
1870 if (!bEmpty) {
1871 if (bClose) {
1872 path.Close();
1873 }
1874 XFA_BOX_StrokePath(strokes[7], &path, pGS, pMatrix);
1875 }
1876 }
1877 static void XFA_BOX_Stroke(CXFA_Box box,
1878 const CXFA_StrokeArray& strokes,
1879 CFX_Graphics* pGS,
1880 CFX_RectF rtWidget,
1881 CFX_Matrix* pMatrix,
1882 FX_DWORD dwFlags) {
1883 if (box.IsArc() || (dwFlags & XFA_DRAWBOX_ForceRound) != 0) {
1884 XFA_BOX_StrokeArc(box, pGS, rtWidget, pMatrix, dwFlags);
1885 return;
1886 }
1887 bool bVisible = false;
1888 for (int32_t j = 0; j < 4; j++) {
1889 if (strokes[j * 2 + 1].IsVisible()) {
1890 bVisible = true;
1891 break;
1892 }
1893 }
1894 if (!bVisible) {
1895 return;
1896 }
1897 for (int32_t i = 1; i < 8; i += 2) {
1898 CXFA_Edge edge(strokes[i].GetNode());
1899 FX_FLOAT fThickness = edge.GetThickness();
1900 if (fThickness < 0) {
1901 fThickness = 0;
1902 }
1903 FX_FLOAT fHalf = fThickness / 2;
1904 int32_t iHand = box.GetHand();
1905 switch (i) {
1906 case 1:
1907 if (iHand == XFA_ATTRIBUTEENUM_Left) {
1908 rtWidget.top -= fHalf;
1909 rtWidget.height += fHalf;
1910 } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
1911 rtWidget.top += fHalf;
1912 rtWidget.height -= fHalf;
1913 }
1914 break;
1915 case 3:
1916 if (iHand == XFA_ATTRIBUTEENUM_Left) {
1917 rtWidget.width += fHalf;
1918 } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
1919 rtWidget.width -= fHalf;
1920 }
1921 break;
1922 case 5:
1923 if (iHand == XFA_ATTRIBUTEENUM_Left) {
1924 rtWidget.height += fHalf;
1925 } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
1926 rtWidget.height -= fHalf;
1927 }
1928 break;
1929 case 7:
1930 if (iHand == XFA_ATTRIBUTEENUM_Left) {
1931 rtWidget.left -= fHalf;
1932 rtWidget.width += fHalf;
1933 } else if (iHand == XFA_ATTRIBUTEENUM_Right) {
1934 rtWidget.left += fHalf;
1935 rtWidget.width -= fHalf;
1936 }
1937 break;
1938 }
1939 }
1940 XFA_BOX_Stroke_Rect(box, strokes, pGS, rtWidget, pMatrix);
1941 }
1942 void XFA_DrawBox(CXFA_Box box,
1943 CFX_Graphics* pGS,
1944 const CFX_RectF& rtWidget,
1945 CFX_Matrix* pMatrix,
1946 FX_DWORD dwFlags) {
1947 if (!box || box.GetPresence() != XFA_ATTRIBUTEENUM_Visible) {
1948 return;
1949 }
1950 int32_t iType = box.GetClassID();
1951 if (iType != XFA_ELEMENT_Arc && iType != XFA_ELEMENT_Border &&
1952 iType != XFA_ELEMENT_Rectangle) {
1953 return;
1954 }
1955 CXFA_StrokeArray strokes;
1956 if (!(dwFlags & XFA_DRAWBOX_ForceRound) && iType != XFA_ELEMENT_Arc) {
1957 box.GetStrokes(strokes);
1958 }
1959 XFA_BOX_Fill(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
1960 XFA_BOX_Stroke(box, strokes, pGS, rtWidget, pMatrix, dwFlags);
1961 }
OLDNEW
« no previous file with comments | « xfa/src/fxfa/app/xfa_ffwidget.h ('k') | xfa/src/fxfa/app/xfa_ffwidgetacc.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698