summaryrefslogtreecommitdiff
path: root/xfa/src/fdp
diff options
context:
space:
mode:
Diffstat (limited to 'xfa/src/fdp')
-rw-r--r--xfa/src/fdp/include/fde.h20
-rw-r--r--xfa/src/fdp/include/fde_brs.h143
-rw-r--r--xfa/src/fdp/include/fde_css.h1082
-rw-r--r--xfa/src/fdp/include/fde_img.h76
-rw-r--r--xfa/src/fdp/include/fde_mem.h23
-rw-r--r--xfa/src/fdp/include/fde_pen.h61
-rw-r--r--xfa/src/fdp/include/fde_psr.h94
-rw-r--r--xfa/src/fdp/include/fde_pth.h29
-rw-r--r--xfa/src/fdp/include/fde_rdr.h32
-rw-r--r--xfa/src/fdp/include/fde_rdv.h53
-rw-r--r--xfa/src/fdp/include/fde_tto.h69
-rw-r--r--xfa/src/fdp/include/fde_xml.h188
-rw-r--r--xfa/src/fdp/src/css/fde_csscache.cpp163
-rw-r--r--xfa/src/fdp/src/css/fde_csscache.h97
-rw-r--r--xfa/src/fdp/src/css/fde_cssdatatable.cpp729
-rw-r--r--xfa/src/fdp/src/css/fde_cssdatatable.h195
-rw-r--r--xfa/src/fdp/src/css/fde_cssdeclaration.cpp1193
-rw-r--r--xfa/src/fdp/src/css/fde_cssdeclaration.h70
-rw-r--r--xfa/src/fdp/src/css/fde_cssstyleselector.cpp1715
-rw-r--r--xfa/src/fdp/src/css/fde_cssstyleselector.h1000
-rw-r--r--xfa/src/fdp/src/css/fde_cssstylesheet.cpp481
-rw-r--r--xfa/src/fdp/src/css/fde_cssstylesheet.h163
-rw-r--r--xfa/src/fdp/src/css/fde_csssyntax.cpp495
-rw-r--r--xfa/src/fdp/src/css/fde_csssyntax.h135
-rw-r--r--xfa/src/fdp/src/fde/fde_devbasic.cpp70
-rw-r--r--xfa/src/fdp/src/fde/fde_devbasic.h16
-rw-r--r--xfa/src/fdp/src/fde/fde_gdidevice.cpp555
-rw-r--r--xfa/src/fdp/src/fde/fde_gdidevice.h76
-rw-r--r--xfa/src/fdp/src/fde/fde_gedevice.cpp532
-rw-r--r--xfa/src/fdp/src/fde/fde_gedevice.h63
-rw-r--r--xfa/src/fdp/src/fde/fde_geobject.cpp270
-rw-r--r--xfa/src/fdp/src/fde/fde_geobject.h53
-rw-r--r--xfa/src/fdp/src/fde/fde_iterator.cpp101
-rw-r--r--xfa/src/fdp/src/fde/fde_iterator.h33
-rw-r--r--xfa/src/fdp/src/fde/fde_object.cpp27
-rw-r--r--xfa/src/fdp/src/fde/fde_object.h427
-rw-r--r--xfa/src/fdp/src/fde/fde_render.cpp253
-rw-r--r--xfa/src/fdp/src/fde/fde_render.h42
-rw-r--r--xfa/src/fdp/src/tto/fde_textout.cpp952
-rw-r--r--xfa/src/fdp/src/tto/fde_textout.h132
-rw-r--r--xfa/src/fdp/src/xml/fde_xml.cpp2712
-rw-r--r--xfa/src/fdp/src/xml/fde_xml.h443
42 files changed, 15063 insertions, 0 deletions
diff --git a/xfa/src/fdp/include/fde.h b/xfa/src/fdp/include/fde.h
new file mode 100644
index 0000000000..1e2c311188
--- /dev/null
+++ b/xfa/src/fdp/include/fde.h
@@ -0,0 +1,20 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE
+#define _FDE
+#include "fde_mem.h"
+#include "fde_xml.h"
+#include "fde_img.h"
+#include "fde_brs.h"
+#include "fde_pen.h"
+#include "fde_pth.h"
+#include "fde_tto.h"
+#include "fde_psr.h"
+#include "fde_css.h"
+#include "fde_rdv.h"
+#include "fde_rdr.h"
+#endif
diff --git a/xfa/src/fdp/include/fde_brs.h b/xfa/src/fdp/include/fde_brs.h
new file mode 100644
index 0000000000..04a4f48ad5
--- /dev/null
+++ b/xfa/src/fdp/include/fde_brs.h
@@ -0,0 +1,143 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_BRUSH
+#define _FDE_BRUSH
+class IFDE_Image;
+class IFDE_Path;
+class IFDE_Brush;
+class IFDE_SolidBrush;
+class IFDE_HatchBrush;
+class IFDE_TextureBrush;
+class IFDE_LinearGradientBrush;
+#define FDE_BRUSHTYPE_Unknown -1
+#define FDE_BRUSHTYPE_Solid 0
+#define FDE_BRUSHTYPE_Hatch 1
+#define FDE_BRUSHTYPE_Texture 2
+#define FDE_BRUSHTYPE_LinearGradient 3
+#define FDE_BRUSHTYPE_MAX 3
+#define FDE_WRAPMODE_Tile 0
+#define FDE_WRAPMODE_TileFlipX 1
+#define FDE_WRAPMODE_TileFlipY 2
+#define FDE_WRAPMODE_TileFlipXY 3
+#define FDE_WRAPMODE_Clamp 4
+typedef struct _FDE_GRADIENTCOLOR {
+ FX_FLOAT pos;
+ FX_ARGB color;
+} FDE_GRADIENTCOLOR, * FDE_LPGRADIENTCOLOR;
+typedef FDE_GRADIENTCOLOR const * FDE_LPCGRADIENTCOLOR;
+typedef CFX_ArrayTemplate<FDE_GRADIENTCOLOR> CFDE_GradientColors;
+class IFDE_Brush
+{
+public:
+ static IFDE_Brush* Create(FX_INT32 iType);
+ virtual void Release() = 0;
+ virtual FX_INT32 GetType() const = 0;
+};
+class IFDE_SolidBrush : public IFDE_Brush
+{
+public:
+ virtual FX_ARGB GetColor() const = 0;
+ virtual void SetColor(FX_ARGB color) = 0;
+ virtual const CFX_Matrix& GetMatrix() const = 0;
+ virtual void ResetMatrix() = 0;
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy) = 0;
+ virtual void RotateMatrix(FX_FLOAT fRadian) = 0;
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy) = 0;
+ virtual void ConcatMatrix(const CFX_Matrix &matrix) = 0;
+ virtual void SetMatrix(const CFX_Matrix &matrix) = 0;
+};
+#define FDE_HATCHSTYLE_Horizontal 0
+#define FDE_HATCHSTYLE_Vertical 1
+#define FDE_HATCHSTYLE_ForwardDiagonal 2
+#define FDE_HATCHSTYLE_BackwardDiagonal 3
+#define FDE_HATCHSTYLE_Cross 4
+#define FDE_HATCHSTYLE_DiagonalCross 5
+#define FDE_HATCHSTYLE_05Percent 6
+#define FDE_HATCHSTYLE_10Percent 7
+#define FDE_HATCHSTYLE_20Percent 8
+#define FDE_HATCHSTYLE_25Percent 9
+#define FDE_HATCHSTYLE_30Percent 10
+#define FDE_HATCHSTYLE_40Percent 11
+#define FDE_HATCHSTYLE_50Percent 12
+#define FDE_HATCHSTYLE_60Percent 13
+#define FDE_HATCHSTYLE_70Percent 14
+#define FDE_HATCHSTYLE_75Percent 15
+#define FDE_HATCHSTYLE_80Percent 16
+#define FDE_HATCHSTYLE_90Percent 17
+#define FDE_HATCHSTYLE_LightDownwardDiagonal 18
+#define FDE_HATCHSTYLE_LightUpwardDiagonal 19
+#define FDE_HATCHSTYLE_DarkDownwardDiagonal 20
+#define FDE_HATCHSTYLE_DarkUpwardDiagonal 21
+#define FDE_HATCHSTYLE_WideDownwardDiagonal 22
+#define FDE_HATCHSTYLE_WideUpwardDiagonal 23
+#define FDE_HATCHSTYLE_LightVertical 24
+#define FDE_HATCHSTYLE_LightHorizontal 25
+#define FDE_HATCHSTYLE_NarrowVertical 26
+#define FDE_HATCHSTYLE_NarrowHorizontal 27
+#define FDE_HATCHSTYLE_DarkVertical 28
+#define FDE_HATCHSTYLE_DarkHorizontal 29
+#define FDE_HATCHSTYLE_DashedDownwardDiagonal 30
+#define FDE_HATCHSTYLE_DashedUpwardDiagonal 31
+#define FDE_HATCHSTYLE_DashedHorizontal 32
+#define FDE_HATCHSTYLE_DashedVertical 33
+#define FDE_HATCHSTYLE_SmallConfetti 34
+#define FDE_HATCHSTYLE_LargeConfetti 35
+#define FDE_HATCHSTYLE_ZigZag 36
+#define FDE_HATCHSTYLE_Wave 37
+#define FDE_HATCHSTYLE_DiagonalBrick 38
+#define FDE_HATCHSTYLE_HorizontalBrick 39
+#define FDE_HATCHSTYLE_Weave 40
+#define FDE_HATCHSTYLE_Plaid 41
+#define FDE_HATCHSTYLE_Divot 42
+#define FDE_HATCHSTYLE_DottedGrid 43
+#define FDE_HATCHSTYLE_DottedDiamond 44
+#define FDE_HATCHSTYLE_Shingle 45
+#define FDE_HATCHSTYLE_Trellis 46
+#define FDE_HATCHSTYLE_Sphere 47
+#define FDE_HATCHSTYLE_SmallGrid 48
+#define FDE_HATCHSTYLE_SmallCheckerBoard 49
+#define FDE_HATCHSTYLE_LargeCheckerBoard 50
+#define FDE_HATCHSTYLE_OutlinedDiamond 51
+#define FDE_HATCHSTYLE_SolidDiamond 52
+#define FDE_HATCHSTYLE_Total 53
+#define FDE_HATCHSTYLE_LargeGrid FDE_HATCHSTYLE_Cross
+#define FDE_HATCHSTYLE_Min FDE_HATCHSTYLE_Horizontal
+#define FDE_HATCHSTYLE_Max (FDE_HATCHSTYLE_Total - 1)
+class IFDE_HatchBrush : public IFDE_Brush
+{
+public:
+ virtual FX_ARGB GetColor(FX_BOOL bForegroundColor) const = 0;
+ virtual void SetColor(FX_ARGB color, FX_BOOL bForegroundColor) = 0;
+ virtual FX_INT32 GetHatchStyle() const = 0;
+ virtual FX_BOOL SetHatchStyle(FX_INT32 iHatchStyle) = 0;
+};
+class IFDE_TextureBrush : public IFDE_Brush
+{
+public:
+ virtual IFDE_Image* GetImage() const = 0;
+ virtual void SetImage(IFDE_Image *pImage, FX_BOOL bAutoRelease) = 0;
+ virtual FX_INT32 GetWrapMode() const = 0;
+ virtual void SetWrapMode(FX_INT32 iWrapMode) = 0;
+};
+#define FDE_LINEARGRADIENTMODE_Horizontal 0
+#define FDE_LINEARGRADIENTMODE_Vertical 1
+#define FDE_LINEARGRADIENTMODE_ForwardDiagonal 2
+#define FDE_LINEARGRADIENTMODE_BackwardDiagonal 3
+class IFDE_LinearGradientBrush : public IFDE_Brush
+{
+public:
+ virtual void GetLinearPoints(CFX_PointF &startingPoint, CFX_PointF &endingPoint) const = 0;
+ virtual void SetLinearPoints(const CFX_PointF &startingPoint, const CFX_PointF &endingPoint) = 0;
+ virtual void GetLinearColors(FX_ARGB &startingColor, FX_ARGB &endingColor) const = 0;
+ virtual void SetLinearColors(const FX_ARGB &startingColor, const FX_ARGB &endingColor) = 0;
+ virtual FX_INT32 CountGradientColors() const = 0;
+ virtual FX_BOOL GetGradientColors(CFDE_GradientColors &colors) const = 0;
+ virtual FX_BOOL SetGradientColors(const CFDE_GradientColors &colors) = 0;
+ virtual FX_INT32 GetWrapMode() const = 0;
+ virtual void SetWrapMode(FX_INT32 iWrapMode) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_css.h b/xfa/src/fdp/include/fde_css.h
new file mode 100644
index 0000000000..2870c8d27a
--- /dev/null
+++ b/xfa/src/fdp/include/fde_css.h
@@ -0,0 +1,1082 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSS
+#define _FDE_CSS
+class IFDE_HTMNotify;
+class IFDE_CSSValue;
+class IFDE_CSSPrimitiveValue;
+class IFDE_CSSValueList;
+class IFDE_CSSDeclaration;
+class IFDE_CSSSelector;
+class IFDE_CSSRule;
+class IFDE_CSSStyleRule;
+class IFDE_CSSMediaRule;
+class IFDE_CSSFontFaceRule;
+class IFDE_CSSStyleSheet;
+class IFDE_CSSStyleSheetCache;
+class IFDE_CSSSyntaxParser;
+class IFDE_CSSRubyStyle;
+class IFDE_CSSMultiColumnStyle;
+class IFDE_CSSGeneratedContentStyle;
+class IFDE_CSSFontStyle;
+class IFDE_CSSBoundaryStyle;
+class IFDE_CSSPositionStyle;
+class IFDE_CSSParagraphStyle;
+class IFDE_CSSBackgroundStyle;
+class IFDE_CSSListStyle;
+class IFDE_CSSTableStyle;
+class IFDE_CSSVisualStyle;
+class IFDE_CSSComputedStyle;
+class IFDE_CSSTagProvider;
+class IFDE_CSSAccelerator;
+class IFDE_CSSStyleSelector;
+class IFDE_CSSCounterContext;
+class IFDE_CSSCounterManager;
+class IFDE_CSSQuoteContext;
+class IFDE_CSSContentContext;
+class IFDE_CSSMultiColumnContext;
+class IFDE_CSSFloatContext;
+enum FDE_CSSVALUETYPE {
+ FDE_CSSVALUETYPE_Primitive = 1,
+ FDE_CSSVALUETYPE_List = 2,
+ FDE_CSSVALUETYPE_Shorthand,
+};
+enum FDE_CSSPRIMITIVETYPE {
+ FDE_CSSPRIMITIVETYPE_Unknown = 0,
+ FDE_CSSPRIMITIVETYPE_Number = 1,
+ FDE_CSSPRIMITIVETYPE_Percent = 2,
+ FDE_CSSPRIMITIVETYPE_EMS = 3,
+ FDE_CSSPRIMITIVETYPE_EXS = 4,
+ FDE_CSSPRIMITIVETYPE_PX = 5,
+ FDE_CSSPRIMITIVETYPE_CM = 6,
+ FDE_CSSPRIMITIVETYPE_MM = 7,
+ FDE_CSSPRIMITIVETYPE_IN = 8,
+ FDE_CSSPRIMITIVETYPE_PT = 9,
+ FDE_CSSPRIMITIVETYPE_PC = 10,
+ FDE_CSSPRIMITIVETYPE_String = 19,
+ FDE_CSSPRIMITIVETYPE_URI = 20,
+ FDE_CSSPRIMITIVETYPE_RGB = 25,
+ FDE_CSSPRIMITIVETYPE_Enum,
+ FDE_CSSPRIMITIVETYPE_Function,
+};
+enum FDE_CSSPROPERTYVALUE {
+ FDE_CSSPROPERTYVALUE_Bolder,
+ FDE_CSSPROPERTYVALUE_LowerLatin,
+ FDE_CSSPROPERTYVALUE_Lowercase,
+ FDE_CSSPROPERTYVALUE_LowerGreek,
+ FDE_CSSPROPERTYVALUE_Sesame,
+ FDE_CSSPROPERTYVALUE_None,
+ FDE_CSSPROPERTYVALUE_NwResize,
+ FDE_CSSPROPERTYVALUE_WResize,
+ FDE_CSSPROPERTYVALUE_Dot,
+ FDE_CSSPROPERTYVALUE_End,
+ FDE_CSSPROPERTYVALUE_Ltr,
+ FDE_CSSPROPERTYVALUE_Pre,
+ FDE_CSSPROPERTYVALUE_Rtl,
+ FDE_CSSPROPERTYVALUE_Sub,
+ FDE_CSSPROPERTYVALUE_Top,
+ FDE_CSSPROPERTYVALUE_Visible,
+ FDE_CSSPROPERTYVALUE_Filled,
+ FDE_CSSPROPERTYVALUE_SwResize,
+ FDE_CSSPROPERTYVALUE_NoRepeat,
+ FDE_CSSPROPERTYVALUE_Default,
+ FDE_CSSPROPERTYVALUE_Transparent,
+ FDE_CSSPROPERTYVALUE_Ridge,
+ FDE_CSSPROPERTYVALUE_Right,
+ FDE_CSSPROPERTYVALUE_HorizontalTb,
+ FDE_CSSPROPERTYVALUE_DistributeLetter,
+ FDE_CSSPROPERTYVALUE_DoubleCircle,
+ FDE_CSSPROPERTYVALUE_Ruby,
+ FDE_CSSPROPERTYVALUE_Collapse,
+ FDE_CSSPROPERTYVALUE_Normal,
+ FDE_CSSPROPERTYVALUE_Avoid,
+ FDE_CSSPROPERTYVALUE_UpperRoman,
+ FDE_CSSPROPERTYVALUE_Auto,
+ FDE_CSSPROPERTYVALUE_Text,
+ FDE_CSSPROPERTYVALUE_XSmall,
+ FDE_CSSPROPERTYVALUE_Thin,
+ FDE_CSSPROPERTYVALUE_Repeat,
+ FDE_CSSPROPERTYVALUE_Small,
+ FDE_CSSPROPERTYVALUE_NeResize,
+ FDE_CSSPROPERTYVALUE_NoContent,
+ FDE_CSSPROPERTYVALUE_Outside,
+ FDE_CSSPROPERTYVALUE_EResize,
+ FDE_CSSPROPERTYVALUE_TableRow,
+ FDE_CSSPROPERTYVALUE_Bottom,
+ FDE_CSSPROPERTYVALUE_Underline,
+ FDE_CSSPROPERTYVALUE_CjkIdeographic,
+ FDE_CSSPROPERTYVALUE_SeResize,
+ FDE_CSSPROPERTYVALUE_Fixed,
+ FDE_CSSPROPERTYVALUE_Double,
+ FDE_CSSPROPERTYVALUE_Solid,
+ FDE_CSSPROPERTYVALUE_RubyBaseGroup,
+ FDE_CSSPROPERTYVALUE_OpenQuote,
+ FDE_CSSPROPERTYVALUE_Lighter,
+ FDE_CSSPROPERTYVALUE_LowerRoman,
+ FDE_CSSPROPERTYVALUE_Strict,
+ FDE_CSSPROPERTYVALUE_TableCaption,
+ FDE_CSSPROPERTYVALUE_Oblique,
+ FDE_CSSPROPERTYVALUE_Decimal,
+ FDE_CSSPROPERTYVALUE_Loose,
+ FDE_CSSPROPERTYVALUE_Hebrew,
+ FDE_CSSPROPERTYVALUE_Hidden,
+ FDE_CSSPROPERTYVALUE_Dashed,
+ FDE_CSSPROPERTYVALUE_Embed,
+ FDE_CSSPROPERTYVALUE_TableRowGroup,
+ FDE_CSSPROPERTYVALUE_TableColumn,
+ FDE_CSSPROPERTYVALUE_Static,
+ FDE_CSSPROPERTYVALUE_Outset,
+ FDE_CSSPROPERTYVALUE_DecimalLeadingZero,
+ FDE_CSSPROPERTYVALUE_KeepWords,
+ FDE_CSSPROPERTYVALUE_KatakanaIroha,
+ FDE_CSSPROPERTYVALUE_Super,
+ FDE_CSSPROPERTYVALUE_Center,
+ FDE_CSSPROPERTYVALUE_TableHeaderGroup,
+ FDE_CSSPROPERTYVALUE_Inside,
+ FDE_CSSPROPERTYVALUE_XxLarge,
+ FDE_CSSPROPERTYVALUE_Triangle,
+ FDE_CSSPROPERTYVALUE_RubyTextGroup,
+ FDE_CSSPROPERTYVALUE_Circle,
+ FDE_CSSPROPERTYVALUE_Hiragana,
+ FDE_CSSPROPERTYVALUE_RepeatX,
+ FDE_CSSPROPERTYVALUE_RepeatY,
+ FDE_CSSPROPERTYVALUE_Move,
+ FDE_CSSPROPERTYVALUE_HiraganaIroha,
+ FDE_CSSPROPERTYVALUE_RubyBase,
+ FDE_CSSPROPERTYVALUE_Scroll,
+ FDE_CSSPROPERTYVALUE_Smaller,
+ FDE_CSSPROPERTYVALUE_TableFooterGroup,
+ FDE_CSSPROPERTYVALUE_Baseline,
+ FDE_CSSPROPERTYVALUE_Separate,
+ FDE_CSSPROPERTYVALUE_Armenian,
+ FDE_CSSPROPERTYVALUE_Open,
+ FDE_CSSPROPERTYVALUE_Relative,
+ FDE_CSSPROPERTYVALUE_Thick,
+ FDE_CSSPROPERTYVALUE_Justify,
+ FDE_CSSPROPERTYVALUE_Middle,
+ FDE_CSSPROPERTYVALUE_Always,
+ FDE_CSSPROPERTYVALUE_DistributeSpace,
+ FDE_CSSPROPERTYVALUE_LineEdge,
+ FDE_CSSPROPERTYVALUE_PreWrap,
+ FDE_CSSPROPERTYVALUE_Medium,
+ FDE_CSSPROPERTYVALUE_NResize,
+ FDE_CSSPROPERTYVALUE_ListItem,
+ FDE_CSSPROPERTYVALUE_Show,
+ FDE_CSSPROPERTYVALUE_Currentcolor,
+ FDE_CSSPROPERTYVALUE_NoCloseQuote,
+ FDE_CSSPROPERTYVALUE_VerticalLr,
+ FDE_CSSPROPERTYVALUE_VerticalRl,
+ FDE_CSSPROPERTYVALUE_Pointer,
+ FDE_CSSPROPERTYVALUE_XxSmall,
+ FDE_CSSPROPERTYVALUE_Bold,
+ FDE_CSSPROPERTYVALUE_Both,
+ FDE_CSSPROPERTYVALUE_SmallCaps,
+ FDE_CSSPROPERTYVALUE_Katakana,
+ FDE_CSSPROPERTYVALUE_After,
+ FDE_CSSPROPERTYVALUE_Horizontal,
+ FDE_CSSPROPERTYVALUE_Dotted,
+ FDE_CSSPROPERTYVALUE_Disc,
+ FDE_CSSPROPERTYVALUE_Georgian,
+ FDE_CSSPROPERTYVALUE_Inline,
+ FDE_CSSPROPERTYVALUE_Overline,
+ FDE_CSSPROPERTYVALUE_Wait,
+ FDE_CSSPROPERTYVALUE_BreakAll,
+ FDE_CSSPROPERTYVALUE_UpperAlpha,
+ FDE_CSSPROPERTYVALUE_Capitalize,
+ FDE_CSSPROPERTYVALUE_Nowrap,
+ FDE_CSSPROPERTYVALUE_TextBottom,
+ FDE_CSSPROPERTYVALUE_NoOpenQuote,
+ FDE_CSSPROPERTYVALUE_Groove,
+ FDE_CSSPROPERTYVALUE_Progress,
+ FDE_CSSPROPERTYVALUE_Larger,
+ FDE_CSSPROPERTYVALUE_CloseQuote,
+ FDE_CSSPROPERTYVALUE_TableCell,
+ FDE_CSSPROPERTYVALUE_PreLine,
+ FDE_CSSPROPERTYVALUE_Absolute,
+ FDE_CSSPROPERTYVALUE_InlineTable,
+ FDE_CSSPROPERTYVALUE_BidiOverride,
+ FDE_CSSPROPERTYVALUE_InlineBlock,
+ FDE_CSSPROPERTYVALUE_Inset,
+ FDE_CSSPROPERTYVALUE_Crosshair,
+ FDE_CSSPROPERTYVALUE_UpperLatin,
+ FDE_CSSPROPERTYVALUE_Help,
+ FDE_CSSPROPERTYVALUE_Hide,
+ FDE_CSSPROPERTYVALUE_Uppercase,
+ FDE_CSSPROPERTYVALUE_SResize,
+ FDE_CSSPROPERTYVALUE_Table,
+ FDE_CSSPROPERTYVALUE_Blink,
+ FDE_CSSPROPERTYVALUE_Block,
+ FDE_CSSPROPERTYVALUE_Start,
+ FDE_CSSPROPERTYVALUE_TableColumnGroup,
+ FDE_CSSPROPERTYVALUE_Italic,
+ FDE_CSSPROPERTYVALUE_LineThrough,
+ FDE_CSSPROPERTYVALUE_KeepAll,
+ FDE_CSSPROPERTYVALUE_LowerAlpha,
+ FDE_CSSPROPERTYVALUE_RunIn,
+ FDE_CSSPROPERTYVALUE_Square,
+ FDE_CSSPROPERTYVALUE_XLarge,
+ FDE_CSSPROPERTYVALUE_Large,
+ FDE_CSSPROPERTYVALUE_Before,
+ FDE_CSSPROPERTYVALUE_Left,
+ FDE_CSSPROPERTYVALUE_TextTop,
+ FDE_CSSPROPERTYVALUE_RubyText,
+ FDE_CSSPROPERTYVALUE_NoDisplay,
+ FDE_CSSPROPERTYVALUE_MAX
+};
+class IFDE_CSSValue
+{
+public:
+ virtual FDE_CSSVALUETYPE GetType() const = 0;
+};
+class IFDE_CSSPrimitiveValue : public IFDE_CSSValue
+{
+public:
+ virtual FDE_CSSVALUETYPE GetType() const
+ {
+ return FDE_CSSVALUETYPE_Primitive;
+ }
+ virtual FDE_CSSPRIMITIVETYPE GetPrimitiveType() const = 0;
+ virtual FX_ARGB GetRGBColor() const = 0;
+ virtual FX_FLOAT GetFloat() const = 0;
+ virtual FX_LPCWSTR GetString(FX_INT32 &iLength) const = 0;
+ virtual FDE_CSSPROPERTYVALUE GetEnum() const = 0;
+ virtual FX_LPCWSTR GetFuncName() const = 0;
+ virtual FX_INT32 CountArgs() const = 0;
+ virtual IFDE_CSSValue* GetArgs(FX_INT32 index) const = 0;
+};
+class IFDE_CSSValueList : public IFDE_CSSValue
+{
+public:
+ virtual FDE_CSSVALUETYPE GetType() const
+ {
+ return FDE_CSSVALUETYPE_List;
+ }
+ virtual FX_INT32 CountValues() const = 0;
+ virtual IFDE_CSSValue* GetValue(FX_INT32 index) const = 0;
+};
+enum FDE_CSSPROPERTY {
+ FDE_CSSPROPERTY_WritingMode,
+ FDE_CSSPROPERTY_ColumnRuleWidth,
+ FDE_CSSPROPERTY_BorderLeft,
+ FDE_CSSPROPERTY_ColumnRule,
+ FDE_CSSPROPERTY_Height,
+ FDE_CSSPROPERTY_CounterReset,
+ FDE_CSSPROPERTY_Content,
+ FDE_CSSPROPERTY_RubyPosition,
+ FDE_CSSPROPERTY_BackgroundColor,
+ FDE_CSSPROPERTY_Width,
+ FDE_CSSPROPERTY_Src,
+ FDE_CSSPROPERTY_Top,
+ FDE_CSSPROPERTY_Margin,
+ FDE_CSSPROPERTY_BorderColor,
+ FDE_CSSPROPERTY_Widows,
+ FDE_CSSPROPERTY_BorderBottomColor,
+ FDE_CSSPROPERTY_TextIndent,
+ FDE_CSSPROPERTY_Right,
+ FDE_CSSPROPERTY_TextEmphasisStyle,
+ FDE_CSSPROPERTY_PaddingLeft,
+ FDE_CSSPROPERTY_ColumnWidth,
+ FDE_CSSPROPERTY_MarginLeft,
+ FDE_CSSPROPERTY_Border,
+ FDE_CSSPROPERTY_BorderTop,
+ FDE_CSSPROPERTY_RubyOverhang,
+ FDE_CSSPROPERTY_PageBreakBefore,
+ FDE_CSSPROPERTY_MaxHeight,
+ FDE_CSSPROPERTY_MinWidth,
+ FDE_CSSPROPERTY_BorderLeftColor,
+ FDE_CSSPROPERTY_Bottom,
+ FDE_CSSPROPERTY_Quotes,
+ FDE_CSSPROPERTY_MaxWidth,
+ FDE_CSSPROPERTY_PaddingRight,
+ FDE_CSSPROPERTY_ListStyleImage,
+ FDE_CSSPROPERTY_WhiteSpace,
+ FDE_CSSPROPERTY_BorderBottom,
+ FDE_CSSPROPERTY_ListStyleType,
+ FDE_CSSPROPERTY_WordBreak,
+ FDE_CSSPROPERTY_OverflowX,
+ FDE_CSSPROPERTY_OverflowY,
+ FDE_CSSPROPERTY_BorderTopColor,
+ FDE_CSSPROPERTY_FontFamily,
+ FDE_CSSPROPERTY_Cursor,
+ FDE_CSSPROPERTY_RubyAlign,
+ FDE_CSSPROPERTY_ColumnRuleColor,
+ FDE_CSSPROPERTY_FontWeight,
+ FDE_CSSPROPERTY_BorderRightStyle,
+ FDE_CSSPROPERTY_MinHeight,
+ FDE_CSSPROPERTY_Color,
+ FDE_CSSPROPERTY_LetterSpacing,
+ FDE_CSSPROPERTY_EmptyCells,
+ FDE_CSSPROPERTY_TextAlign,
+ FDE_CSSPROPERTY_RubySpan,
+ FDE_CSSPROPERTY_Position,
+ FDE_CSSPROPERTY_BorderStyle,
+ FDE_CSSPROPERTY_BorderBottomStyle,
+ FDE_CSSPROPERTY_BorderCollapse,
+ FDE_CSSPROPERTY_ColumnCount,
+ FDE_CSSPROPERTY_BorderRightWidth,
+ FDE_CSSPROPERTY_UnicodeBidi,
+ FDE_CSSPROPERTY_VerticalAlign,
+ FDE_CSSPROPERTY_PaddingTop,
+ FDE_CSSPROPERTY_Columns,
+ FDE_CSSPROPERTY_Overflow,
+ FDE_CSSPROPERTY_TableLayout,
+ FDE_CSSPROPERTY_FontVariant,
+ FDE_CSSPROPERTY_ListStyle,
+ FDE_CSSPROPERTY_BackgroundPosition,
+ FDE_CSSPROPERTY_BorderWidth,
+ FDE_CSSPROPERTY_TextEmphasisColor,
+ FDE_CSSPROPERTY_BorderLeftStyle,
+ FDE_CSSPROPERTY_PageBreakInside,
+ FDE_CSSPROPERTY_TextEmphasis,
+ FDE_CSSPROPERTY_BorderBottomWidth,
+ FDE_CSSPROPERTY_ColumnGap,
+ FDE_CSSPROPERTY_Orphans,
+ FDE_CSSPROPERTY_BorderRight,
+ FDE_CSSPROPERTY_FontSize,
+ FDE_CSSPROPERTY_PageBreakAfter,
+ FDE_CSSPROPERTY_CaptionSide,
+ FDE_CSSPROPERTY_BackgroundRepeat,
+ FDE_CSSPROPERTY_BorderTopStyle,
+ FDE_CSSPROPERTY_BorderSpacing,
+ FDE_CSSPROPERTY_TextTransform,
+ FDE_CSSPROPERTY_FontStyle,
+ FDE_CSSPROPERTY_Font,
+ FDE_CSSPROPERTY_LineHeight,
+ FDE_CSSPROPERTY_MarginRight,
+ FDE_CSSPROPERTY_Float,
+ FDE_CSSPROPERTY_BorderLeftWidth,
+ FDE_CSSPROPERTY_Display,
+ FDE_CSSPROPERTY_Clear,
+ FDE_CSSPROPERTY_ColumnRuleStyle,
+ FDE_CSSPROPERTY_TextCombine,
+ FDE_CSSPROPERTY_ListStylePosition,
+ FDE_CSSPROPERTY_Visibility,
+ FDE_CSSPROPERTY_PaddingBottom,
+ FDE_CSSPROPERTY_BackgroundAttachment,
+ FDE_CSSPROPERTY_BackgroundImage,
+ FDE_CSSPROPERTY_LineBreak,
+ FDE_CSSPROPERTY_Background,
+ FDE_CSSPROPERTY_BorderTopWidth,
+ FDE_CSSPROPERTY_WordSpacing,
+ FDE_CSSPROPERTY_BorderRightColor,
+ FDE_CSSPROPERTY_CounterIncrement,
+ FDE_CSSPROPERTY_Left,
+ FDE_CSSPROPERTY_TextDecoration,
+ FDE_CSSPROPERTY_Padding,
+ FDE_CSSPROPERTY_MarginBottom,
+ FDE_CSSPROPERTY_MarginTop,
+ FDE_CSSPROPERTY_Direction,
+ FDE_CSSPROPERTY_MAX
+};
+class IFDE_CSSDeclaration
+{
+public:
+ virtual IFDE_CSSValue* GetProperty(FDE_CSSPROPERTY eProperty, FX_BOOL &bImportant) const = 0;
+ virtual FX_POSITION GetStartPosition() const = 0;
+ virtual void GetNextProperty(FX_POSITION &pos, FDE_CSSPROPERTY &eProperty, IFDE_CSSValue *&pValue, FX_BOOL &bImportant) const = 0;
+ virtual FX_POSITION GetStartCustom() const = 0;
+ virtual void GetNextCustom(FX_POSITION &pos, CFX_WideString &wsName, CFX_WideString &wsValue) const = 0;
+};
+typedef CFX_ArrayTemplate<IFDE_CSSDeclaration*> CFDE_CSSDeclarationArray;
+enum FDE_CSSPERSUDO {
+ FDE_CSSPERSUDO_After,
+ FDE_CSSPERSUDO_Before,
+ FDE_CSSPERSUDO_NONE
+};
+enum FDE_CSSSELECTORTYPE {
+ FDE_CSSSELECTORTYPE_Element,
+ FDE_CSSSELECTORTYPE_Descendant,
+ FDE_CSSSELECTORTYPE_Class,
+ FDE_CSSSELECTORTYPE_Persudo,
+ FDE_CSSSELECTORTYPE_ID,
+};
+class IFDE_CSSSelector
+{
+public:
+ virtual FDE_CSSSELECTORTYPE GetType() const = 0;
+ virtual FX_DWORD GetNameHash() const = 0;
+ virtual IFDE_CSSSelector* GetNextSelector() const = 0;
+};
+#define FDE_CSSMEDIATYPE_Braille 0x01
+#define FDE_CSSMEDIATYPE_Emboss 0x02
+#define FDE_CSSMEDIATYPE_Handheld 0x04
+#define FDE_CSSMEDIATYPE_Print 0x08
+#define FDE_CSSMEDIATYPE_Projection 0x10
+#define FDE_CSSMEDIATYPE_Screen 0x20
+#define FDE_CSSMEDIATYPE_TTY 0x40
+#define FDE_CSSMEDIATYPE_TV 0x80
+#define FDE_CSSMEDIATYPE_ALL 0xFF
+enum FDE_CSSRULETYPE {
+ FDE_CSSRULETYPE_Unknown = 0,
+ FDE_CSSRULETYPE_Style = 1,
+ FDE_CSSRULETYPE_Media = 4,
+ FDE_CSSRULETYPE_FontFace = 5,
+};
+class IFDE_CSSRule
+{
+public:
+ virtual FDE_CSSRULETYPE GetType() const = 0;
+};
+typedef CFX_MassArrayTemplate<IFDE_CSSRule*> CFDE_CSSRuleArray;
+class IFDE_CSSStyleRule : public IFDE_CSSRule
+{
+public:
+ virtual FDE_CSSRULETYPE GetType() const
+ {
+ return FDE_CSSRULETYPE_Style;
+ }
+ virtual FX_INT32 CountSelectorLists() const = 0;
+ virtual IFDE_CSSSelector* GetSelectorList(FX_INT32 index) const = 0;
+ virtual IFDE_CSSDeclaration* GetDeclaration() const = 0;
+};
+class IFDE_CSSMediaRule : public IFDE_CSSRule
+{
+public:
+ virtual FDE_CSSRULETYPE GetType() const
+ {
+ return FDE_CSSRULETYPE_Media;
+ }
+ virtual FX_DWORD GetMediaList() const = 0;
+ virtual FX_INT32 CountRules() const = 0;
+ virtual IFDE_CSSRule* GetRule(FX_INT32 index) = 0;
+};
+class IFDE_CSSFontFaceRule : public IFDE_CSSRule
+{
+public:
+ virtual FDE_CSSRULETYPE GetType() const
+ {
+ return FDE_CSSRULETYPE_FontFace;
+ }
+ virtual IFDE_CSSDeclaration* GetDeclaration() const = 0;
+};
+class IFDE_CSSStyleSheet : public IFX_Unknown
+{
+public:
+ static IFDE_CSSStyleSheet* LoadHTMLStandardStyleSheet();
+ static IFDE_CSSStyleSheet* LoadFromStream(const CFX_WideString &szUrl, IFX_Stream *pStream, FX_WORD wCodePage, FX_DWORD dwMediaList = FDE_CSSMEDIATYPE_ALL);
+ static IFDE_CSSStyleSheet* LoadFromBuffer(const CFX_WideString &szUrl, FX_LPCWSTR pBuffer, FX_INT32 iBufSize, FX_WORD wCodePage, FX_DWORD dwMediaList = FDE_CSSMEDIATYPE_ALL);
+ virtual FX_BOOL GetUrl(CFX_WideString &szUrl) = 0;
+ virtual FX_DWORD GetMediaList() const = 0;
+ virtual FX_WORD GetCodePage() const = 0;
+
+ virtual FX_INT32 CountRules() const = 0;
+ virtual IFDE_CSSRule* GetRule(FX_INT32 index) = 0;
+};
+typedef CFX_ArrayTemplate<IFDE_CSSStyleSheet*> CFDE_CSSStyleSheetArray;
+#define FDE_CSSUSERSTYLESHEET (FX_BSTRC("#USERSHEET"))
+#define FDE_CSSUAGENTSTYLESHEET (FX_BSTRC("#AGENTSHEET"))
+class IFDE_CSSStyleSheetCache
+{
+public:
+ static IFDE_CSSStyleSheetCache* Create();
+ virtual void Release() = 0;
+ virtual void SetMaxItems(FX_INT32 iMaxCount = 5) = 0;
+ virtual void AddStyleSheet(FX_BSTR szKey, IFDE_CSSStyleSheet *pStyleSheet) = 0;
+ virtual IFDE_CSSStyleSheet* GetStyleSheet(FX_BSTR szKey) const = 0;
+ virtual void RemoveStyleSheet(FX_BSTR szKey) = 0;
+};
+enum FDE_CSSSYNTAXSTATUS {
+ FDE_CSSSYNTAXSTATUS_Error,
+ FDE_CSSSYNTAXSTATUS_EOS,
+ FDE_CSSSYNTAXSTATUS_None,
+ FDE_CSSSYNTAXSTATUS_Charset,
+ FDE_CSSSYNTAXSTATUS_ImportRule,
+ FDE_CSSSYNTAXSTATUS_ImportClose,
+ FDE_CSSSYNTAXSTATUS_PageRule,
+ FDE_CSSSYNTAXSTATUS_StyleRule,
+ FDE_CSSSYNTAXSTATUS_FontFaceRule,
+ FDE_CSSSYNTAXSTATUS_MediaRule,
+ FDE_CSSSYNTAXSTATUS_MediaType,
+ FDE_CSSSYNTAXSTATUS_URI,
+ FDE_CSSSYNTAXSTATUS_Selector,
+ FDE_CSSSYNTAXSTATUS_DeclOpen,
+ FDE_CSSSYNTAXSTATUS_DeclClose,
+ FDE_CSSSYNTAXSTATUS_PropertyName,
+ FDE_CSSSYNTAXSTATUS_PropertyValue,
+};
+class IFDE_CSSSyntaxParser
+{
+public:
+ static IFDE_CSSSyntaxParser* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL Init(IFX_Stream *pStream, FX_INT32 iCSSPlaneSize, FX_INT32 iTextDataSize = 32, FX_BOOL bOnlyDeclaration = FALSE) = 0;
+ virtual FX_BOOL Init(FX_LPCWSTR pBuffer, FX_INT32 iBufferSize, FX_INT32 iTextDatSize = 32, FX_BOOL bOnlyDeclaration = FALSE) = 0;
+
+ virtual FDE_CSSSYNTAXSTATUS DoSyntaxParse() = 0;
+ virtual FX_LPCWSTR GetCurrentString(FX_INT32 &iLength) const = 0;
+};
+enum FDE_CSSLENGTHUNIT {
+ FDE_CSSLENGTHUNIT_Auto,
+ FDE_CSSLENGTHUNIT_None,
+ FDE_CSSLENGTHUNIT_Normal,
+ FDE_CSSLENGTHUNIT_Point,
+ FDE_CSSLENGTHUNIT_Percent,
+};
+#define FDE_CSSUNITBITS (3)
+#define FDE_CSSUNITMASK ((1 << FDE_CSSUNITBITS) - 1)
+struct FDE_CSSLENGTH {
+ FDE_CSSLENGTH& Set(FDE_CSSLENGTHUNIT eUnit)
+ {
+ m_iData = eUnit;
+ return *this;
+ }
+ FDE_CSSLENGTH& Set(FDE_CSSLENGTHUNIT eUnit, FX_FLOAT fValue)
+ {
+ m_iData = ((FX_INTPTR)(fValue * 1024.0f) << FDE_CSSUNITBITS) | eUnit;
+ return *this;
+ }
+ FDE_CSSLENGTHUNIT GetUnit() const
+ {
+ return (FDE_CSSLENGTHUNIT)(m_iData & FDE_CSSUNITMASK);
+ }
+ FX_FLOAT GetValue() const
+ {
+ return (m_iData >> FDE_CSSUNITBITS) / 1024.0f;
+ }
+ FX_BOOL NonZero() const
+ {
+ return (m_iData >> FDE_CSSUNITBITS) != 0;
+ }
+private:
+ FX_INTPTR m_iData;
+};
+struct FDE_CSSPOINT {
+ FDE_CSSPOINT& Set(FDE_CSSLENGTHUNIT eUnit)
+ {
+ x.Set(eUnit);
+ y.Set(eUnit);
+ return *this;
+ }
+ FDE_CSSPOINT& Set(FDE_CSSLENGTHUNIT eUnit, FX_FLOAT fValue)
+ {
+ x.Set(eUnit, fValue);
+ y.Set(eUnit, fValue);
+ return *this;
+ }
+ FDE_CSSLENGTH x, y;
+};
+struct FDE_CSSSIZE {
+ FDE_CSSSIZE& Set(FDE_CSSLENGTHUNIT eUnit)
+ {
+ cx.Set(eUnit);
+ cy.Set(eUnit);
+ return *this;
+ }
+ FDE_CSSSIZE& Set(FDE_CSSLENGTHUNIT eUnit, FX_FLOAT fValue)
+ {
+ cx.Set(eUnit, fValue);
+ cy.Set(eUnit, fValue);
+ return *this;
+ }
+ FDE_CSSLENGTH cx, cy;
+};
+struct FDE_CSSRECT {
+ FDE_CSSRECT& Set(FDE_CSSLENGTHUNIT eUnit)
+ {
+ left.Set(eUnit);
+ top.Set(eUnit);
+ right.Set(eUnit);
+ bottom.Set(eUnit);
+ return *this;
+ }
+ FDE_CSSRECT& Set(FDE_CSSLENGTHUNIT eUnit, FX_FLOAT fValue)
+ {
+ left.Set(eUnit, fValue);
+ top.Set(eUnit, fValue);
+ right.Set(eUnit, fValue);
+ bottom.Set(eUnit, fValue);
+ return *this;
+ }
+
+ FDE_CSSLENGTH left, top, right, bottom;
+};
+enum FDE_CSSBKGATTACHMENT {
+ FDE_CSSBKGATTACHMENT_Scroll,
+ FDE_CSSBKGATTACHMENT_Fixed,
+};
+enum FDE_CSSBKGREPEAT {
+ FDE_CSSBKGREPEAT_Repeat,
+ FDE_CSSBKGREPEAT_RepeatX,
+ FDE_CSSBKGREPEAT_RepeatY,
+ FDE_CSSBKGREPEAT_NoRepeat,
+};
+enum FDE_CSSBORDERSTYLE {
+ FDE_CSSBORDERSTYLE_None,
+ FDE_CSSBORDERSTYLE_Hidden,
+ FDE_CSSBORDERSTYLE_Dotted,
+ FDE_CSSBORDERSTYLE_Dashed,
+ FDE_CSSBORDERSTYLE_Solid,
+ FDE_CSSBORDERSTYLE_Double,
+ FDE_CSSBORDERSTYLE_Groove,
+ FDE_CSSBORDERSTYLE_Ridge,
+ FDE_CSSBORDERSTYLE_Inset,
+ FDE_CSSBORDERSTYLE_outset,
+};
+enum FDE_CSSCLEAR {
+ FDE_CSSCLEAR_None,
+ FDE_CSSCLEAR_Left,
+ FDE_CSSCLEAR_Right,
+ FDE_CSSCLEAR_Both,
+};
+enum FDE_CSSDISPLAY {
+ FDE_CSSDISPLAY_None,
+ FDE_CSSDISPLAY_ListItem,
+ FDE_CSSDISPLAY_RunIn,
+ FDE_CSSDISPLAY_Block,
+ FDE_CSSDISPLAY_Inline,
+ FDE_CSSDISPLAY_InlineBlock,
+ FDE_CSSDISPLAY_InlineTable,
+ FDE_CSSDISPLAY_Table,
+ FDE_CSSDISPLAY_TableRow,
+ FDE_CSSDISPLAY_TableCell,
+ FDE_CSSDISPLAY_TableCaption,
+ FDE_CSSDISPLAY_TableColumn,
+ FDE_CSSDISPLAY_TableRowGroup,
+ FDE_CSSDISPLAY_TableColumnGroup,
+ FDE_CSSDISPLAY_TableHeaderGroup,
+ FDE_CSSDISPLAY_TableFooterGroup,
+ FDE_CSSDISPLAY_Ruby,
+ FDE_CSSDISPLAY_RubyBase,
+ FDE_CSSDISPLAY_RubyText,
+ FDE_CSSDISPLSY_RubyBaseGroup,
+ FDE_CSSDISPLAY_RubyTextGroup,
+};
+enum FDE_CSSVISIBILITY {
+ FDE_CSSVISIBILITY_Visible,
+ FDE_CSSVISIBILITY_Hidden,
+ FDE_CSSVISIBILITY_Collapse,
+};
+enum FDE_CSSFONTSTYLE {
+ FDE_CSSFONTSTYLE_Normal,
+ FDE_CSSFONTSTYLE_Italic,
+};
+enum FDE_CSSFLOAT {
+ FDE_CSSFLOAT_None,
+ FDE_CSSFLOAT_Left,
+ FDE_CSSFLOAT_Right,
+};
+enum FDE_CSSWRITINGMODE {
+ FDE_CSSWRITINGMODE_HorizontalTb,
+ FDE_CSSWRITINGMODE_VerticalRl,
+ FDE_CSSWRITINGMODE_VerticalLr,
+};
+enum FDE_CSSWORDBREAK {
+ FDE_CSSWORDBREAK_Normal,
+ FDE_CSSWORDBREAK_KeepAll,
+ FDE_CSSWORDBREAK_BreakAll,
+ FDE_CSSWORDBREAK_KeepWords,
+};
+enum FDE_CSSPAGEBREAK {
+ FDE_CSSPAGEBREAK_Auto,
+ FDE_CSSPAGEBREAK_Always,
+ FDE_CSSPAGEBREAK_Avoid,
+ FDE_CSSPAGEBREAK_Left,
+ FDE_CSSPAGEBREAK_Right,
+};
+enum FDE_CSSOVERFLOW {
+ FDE_CSSOVERFLOW_Visible,
+ FDE_CSSOVERFLOW_Hidden,
+ FDE_CSSOVERFLOW_Scroll,
+ FDE_CSSOVERFLOW_Auto,
+ FDE_CSSOVERFLOW_NoDisplay,
+ FDE_CSSOVERFLOW_NoContent,
+};
+enum FDE_CSSLINEBREAK {
+ FDE_CSSLINEBREAK_Auto,
+ FDE_CSSLINEBREAK_Loose,
+ FDE_CSSLINEBREAK_Normal,
+ FDE_CSSLINEBREAK_Strict,
+};
+enum FDE_CSSTEXTEMPHASISFILL {
+ FDE_CSSTEXTEMPHASISFILL_Filled,
+ FDE_CSSTEXTEMPHASISFILL_Open,
+};
+enum FDE_CSSTEXTEMPHASISMARK {
+ FDE_CSSTEXTEMPHASISMARK_None,
+ FDE_CSSTEXTEMPHASISMARK_Auto,
+ FDE_CSSTEXTEMPHASISMARK_Dot,
+ FDE_CSSTEXTEMPHASISMARK_Circle,
+ FDE_CSSTEXTEMPHASISMARK_DoubleCircle,
+ FDE_CSSTEXTEMPHASISMARK_Triangle,
+ FDE_CSSTEXTEMPHASISMARK_Sesame,
+ FDE_CSSTEXTEMPHASISMARK_Custom,
+};
+enum FDE_CSSTEXTCOMBINE {
+ FDE_CSSTEXTCOMBINE_Horizontal,
+ FDE_CSSTEXTCOMBINE_None,
+};
+enum FDE_CSSCURSOR {
+ FDE_CSSCURSOR_Auto,
+ FDE_CSSCURSOR_Crosshair,
+ FDE_CSSCURSOR_Default,
+ FDE_CSSCURSOR_Pointer,
+ FDE_CSSCURSOR_Move,
+ FDE_CSSCURSOR_EResize,
+ FDE_CSSCURSOR_NeResize,
+ FDE_CSSCURSOR_NwResize,
+ FDE_CSSCURSOR_NResize,
+ FDE_CSSCURSOR_SeResize,
+ FDE_CSSCURSOR_SwResize,
+ FDE_CSSCURSOR_SResize,
+ FDE_CSSCURSOR_WResize,
+ FDE_CSSCURSOR_Text,
+ FDE_CSSCURSOR_Wait,
+ FDE_CSSCURSOR_Help,
+ FDE_CSSCURSOR_Progress,
+};
+enum FDE_CSSPOSITION {
+ FDE_CSSPOSITION_Static,
+ FDE_CSSPOSITION_Relative,
+ FDE_CSSPOSITION_Absolute,
+ FDE_CSSPOSITION_Fixed,
+};
+enum FDE_CSSCAPTIONSIDE {
+ FDE_CSSCAPTIONSIDE_Top,
+ FDE_CSSCAPTIONSIDE_Bottom,
+ FDE_CSSCAPTIONSIDE_Left,
+ FDE_CSSCAPTIONSIDE_Right,
+ FDE_CSSCAPTIONSIDE_Before,
+ FDE_CSSCAPTIONSIDE_After,
+};
+enum FDE_CSSRUBYALIGN {
+ FDE_CSSRUBYALIGN_Auto,
+ FDE_CSSRUBYALIGN_Start,
+ FDE_CSSRUBYALIGN_Left,
+ FDE_CSSRUBYALIGN_Center,
+ FDE_CSSRUBYALIGN_End,
+ FDE_CSSRUBYALIGN_Right,
+ FDE_CSSRUBYALIGN_DistributeLetter,
+ FDE_CSSRUBYALIGN_DistributeSpace,
+ FDE_CSSRUBYALIGN_LineEdge,
+};
+enum FDE_CSSRUBYOVERHANG {
+ FDE_CSSRUBYOVERHANG_Auto,
+ FDE_CSSRUBYOVERHANG_Start,
+ FDE_CSSRUBYOVERHANG_End,
+ FDE_CSSRUBYOVERHANG_None,
+};
+enum FDE_CSSRUBYPOSITION {
+ FDE_CSSRUBYPOSITION_Before,
+ FDE_CSSRUBYPOSITION_After,
+ FDE_CSSRUBYPOSITION_Right,
+ FDE_CSSRUBYPOSITION_Inline,
+};
+enum FDE_CSSRUBYSPAN {
+ FDE_CSSRUBYSPAN_None,
+ FDE_CSSRUBYSPAN_Attr,
+};
+enum FDE_CSSTEXTALIGN {
+ FDE_CSSTEXTALIGN_Left,
+ FDE_CSSTEXTALIGN_Right,
+ FDE_CSSTEXTALIGN_Center,
+ FDE_CSSTEXTALIGN_Justify,
+ FDE_CSSTEXTALIGN_JustifyAll,
+};
+enum FDE_CSSVERTICALALIGN {
+ FDE_CSSVERTICALALIGN_Baseline,
+ FDE_CSSVERTICALALIGN_Sub,
+ FDE_CSSVERTICALALIGN_Super,
+ FDE_CSSVERTICALALIGN_Top,
+ FDE_CSSVERTICALALIGN_TextTop,
+ FDE_CSSVERTICALALIGN_Middle,
+ FDE_CSSVERTICALALIGN_Bottom,
+ FDE_CSSVERTICALALIGN_TextBottom,
+ FDE_CSSVERTICALALIGN_Number,
+};
+enum FDE_CSSLISTSTYLETYPE {
+ FDE_CSSLISTSTYLETYPE_Disc,
+ FDE_CSSLISTSTYLETYPE_Circle,
+ FDE_CSSLISTSTYLETYPE_Square,
+ FDE_CSSLISTSTYLETYPE_Decimal,
+ FDE_CSSLISTSTYLETYPE_DecimalLeadingZero,
+ FDE_CSSLISTSTYLETYPE_LowerRoman,
+ FDE_CSSLISTSTYLETYPE_UpperRoman,
+ FDE_CSSLISTSTYLETYPE_LowerGreek,
+ FDE_CSSLISTSTYLETYPE_LowerLatin,
+ FDE_CSSLISTSTYLETYPE_UpperLatin,
+ FDE_CSSLISTSTYLETYPE_Armenian,
+ FDE_CSSLISTSTYLETYPE_Georgian,
+ FDE_CSSLISTSTYLETYPE_LowerAlpha,
+ FDE_CSSLISTSTYLETYPE_UpperAlpha,
+ FDE_CSSLISTSTYLETYPE_None,
+ FDE_CSSLISTSTYLETYPE_CjkIdeographic,
+ FDE_CSSLISTSTYLETYPE_Hebrew,
+ FDE_CSSLISTSTYLETYPE_Hiragana,
+ FDE_CSSLISTSTYLETYPE_HiraganaIroha,
+ FDE_CSSLISTSTYLETYPE_Katakana,
+ FDE_CSSLISTSTYLETYPE_KatakanaIroha,
+};
+enum FDE_CSSLISTSTYLEPOSITION {
+ FDE_CSSLISTSTYLEPOSITION_Outside,
+ FDE_CSSLISTSTYLEPOSITION_Inside,
+};
+enum FDE_CSSWHITESPACE {
+ FDE_CSSWHITESPACE_Normal,
+ FDE_CSSWHITESPACE_Pre,
+ FDE_CSSWHITESPACE_Nowrap,
+ FDE_CSSWHITESPACE_PreWrap,
+ FDE_CSSWHITESPACE_PreLine,
+};
+enum FDE_CSSFONTVARIANT {
+ FDE_CSSFONTVARIANT_Normal,
+ FDE_CSSFONTVARIANT_SmallCaps,
+};
+enum FDE_CSSTEXTTRANSFORM {
+ FDE_CSSTEXTTRANSFORM_None,
+ FDE_CSSTEXTTRANSFORM_Capitalize,
+ FDE_CSSTEXTTRANSFORM_UpperCase,
+ FDE_CSSTEXTTRANSFORM_LowerCase,
+};
+enum FDE_CSSTEXTDECORATION {
+ FDE_CSSTEXTDECORATION_None = 0,
+ FDE_CSSTEXTDECORATION_Underline = 1,
+ FDE_CSSTEXTDECORATION_Overline = 2,
+ FDE_CSSTEXTDECORATION_LineThrough = 4,
+ FDE_CSSTEXTDECORATION_Blink = 8,
+ FDE_CSSTEXTDECORATION_Double = 16,
+};
+class IFDE_CSSRubyStyle
+{
+public:
+ virtual FDE_CSSRUBYALIGN GetRubyAlign() const = 0;
+ virtual FDE_CSSRUBYOVERHANG GetRubyOverhang() const = 0;
+ virtual FDE_CSSRUBYPOSITION GetRubyPosition() const = 0;
+ virtual FDE_CSSRUBYSPAN GetRubySpanType() const = 0;
+ virtual IFDE_CSSValue* GetRubySpanAttr() const = 0;
+};
+class IFDE_CSSMultiColumnStyle
+{
+public:
+ virtual const FDE_CSSLENGTH& GetColumnCount() const = 0;
+ virtual const FDE_CSSLENGTH& GetColumnGap() const = 0;
+ virtual FX_ARGB GetColumnRuleColor() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetColumnRuleStyle() const = 0;
+ virtual const FDE_CSSLENGTH& GetColumnRuleWidth() const = 0;
+ virtual const FDE_CSSLENGTH& GetColumnWidth() const = 0;
+ virtual void SetColumnCount(const FDE_CSSLENGTH &columnCount) = 0;
+ virtual void SetColumnGap(const FDE_CSSLENGTH &columnGap) = 0;
+ virtual void SetColumnRuleColor(FX_ARGB dwColumnRuleColor) = 0;
+ virtual void SetColumnRuleStyle(FDE_CSSBORDERSTYLE eColumnRuleStyle) = 0;
+ virtual void SetColumnRuleWidth(const FDE_CSSLENGTH &columnRuleWidth) = 0;
+ virtual void SetColumnWidth(const FDE_CSSLENGTH &columnWidth) = 0;
+};
+class IFDE_CSSGeneratedContentStyle
+{
+public:
+ virtual FX_INT32 CountCounters() = 0;
+ virtual FX_LPCWSTR GetCounterIdentifier(FX_INT32 index) = 0;
+ virtual FX_BOOL GetCounterReset(FX_INT32 index, FX_INT32 &iValue) = 0;
+ virtual FX_BOOL GetCounterIncrement(FX_INT32 index, FX_INT32 &iValue) = 0;
+ virtual IFDE_CSSValueList* GetContent() const = 0;
+ virtual FX_INT32 CountQuotes() const = 0;
+ virtual FX_LPCWSTR GetQuotes(FX_INT32 index) const = 0;
+};
+class IFDE_CSSFontStyle
+{
+public:
+ virtual FX_INT32 CountFontFamilies() const = 0;
+ virtual FX_LPCWSTR GetFontFamily(FX_INT32 index) const = 0;
+ virtual FX_WORD GetFontWeight() const = 0;
+ virtual FDE_CSSFONTVARIANT GetFontVariant() const = 0;
+ virtual FDE_CSSFONTSTYLE GetFontStyle() const = 0;
+ virtual FX_FLOAT GetFontSize() const = 0;
+ virtual FX_ARGB GetColor() const = 0;
+ virtual void SetFontWeight(FX_WORD wFontWeight) = 0;
+ virtual void SetFontVariant(FDE_CSSFONTVARIANT eFontVariant) = 0;
+ virtual void SetFontStyle(FDE_CSSFONTSTYLE eFontStyle) = 0;
+ virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
+ virtual void SetColor(FX_ARGB dwFontColor) = 0;
+};
+class IFDE_CSSBoundaryStyle
+{
+public:
+ virtual FX_ARGB GetBorderLeftColor() const = 0;
+ virtual FX_ARGB GetBorderTopColor() const = 0;
+ virtual FX_ARGB GetBorderRightColor() const = 0;
+ virtual FX_ARGB GetBorderBottomColor() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetBorderLeftStyle() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetBorderTopStyle() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetBorderRightStyle() const = 0;
+ virtual FDE_CSSBORDERSTYLE GetBorderBottomStyle() const = 0;
+ virtual const FDE_CSSRECT* GetBorderWidth() const = 0;
+ virtual const FDE_CSSRECT* GetMarginWidth() const = 0;
+ virtual const FDE_CSSRECT* GetPaddingWidth() const = 0;
+ virtual void SetBorderLeftColor(FX_ARGB dwBorderColor) = 0;
+ virtual void SetBorderTopColor(FX_ARGB dwBorderColor) = 0;
+ virtual void SetBorderRightColor(FX_ARGB dwBorderColor) = 0;
+ virtual void SetBorderBottomColor(FX_ARGB dwBorderColor) = 0;
+
+ virtual void SetBorderLeftStyle(FDE_CSSBORDERSTYLE eBorderStyle) = 0;
+ virtual void SetBorderTopStyle(FDE_CSSBORDERSTYLE eBorderStyle) = 0;
+ virtual void SetBorderRightStyle(FDE_CSSBORDERSTYLE eBorderStyle) = 0;
+ virtual void SetBorderBottomStyle(FDE_CSSBORDERSTYLE eBorderStyle) = 0;
+
+ virtual void SetBorderWidth(const FDE_CSSRECT &rect) = 0;
+ virtual void SetMarginWidth(const FDE_CSSRECT &rect) = 0;
+ virtual void SetPaddingWidth(const FDE_CSSRECT &rect) = 0;
+};
+class IFDE_CSSPositionStyle
+{
+public:
+ virtual FDE_CSSDISPLAY GetDisplay() const = 0;
+ virtual const FDE_CSSSIZE& GetBoxSize() const = 0;
+ virtual const FDE_CSSSIZE& GetMinBoxSize() const = 0;
+ virtual const FDE_CSSSIZE& GetMaxBoxSize() const = 0;
+ virtual FDE_CSSFLOAT GetFloat() const = 0;
+ virtual FDE_CSSCLEAR GetClear() const = 0;
+ virtual FDE_CSSPOSITION GetPosition() const = 0;
+ virtual FDE_CSSLENGTH GetTop() const = 0;
+ virtual FDE_CSSLENGTH GetBottom() const = 0;
+ virtual FDE_CSSLENGTH GetLeft() const = 0;
+ virtual FDE_CSSLENGTH GetRight() const = 0;
+ virtual void SetDisplay(FDE_CSSDISPLAY eDisplay) = 0;
+ virtual void SetBoxSize(const FDE_CSSSIZE &boxSize) = 0;
+ virtual void SetMinBoxSize(const FDE_CSSSIZE &minBoxSize) = 0;
+ virtual void SetMaxBoxSize(const FDE_CSSSIZE &maxBoxSize) = 0;
+ virtual void SetFloat(FDE_CSSFLOAT eFloat) = 0;
+ virtual void SetClear(FDE_CSSCLEAR eClear) = 0;
+};
+class IFDE_CSSParagraphStyle
+{
+public:
+ virtual FX_FLOAT GetLineHeight() const = 0;
+ virtual FDE_CSSWHITESPACE GetWhiteSpace() const = 0;
+ virtual const FDE_CSSLENGTH& GetTextIndent() const = 0;
+ virtual FDE_CSSTEXTALIGN GetTextAlign() const = 0;
+ virtual FDE_CSSVERTICALALIGN GetVerticalAlign() const = 0;
+ virtual FX_FLOAT GetNumberVerticalAlign() const = 0;
+ virtual FDE_CSSTEXTTRANSFORM GetTextTransform() const = 0;
+ virtual FX_DWORD GetTextDecoration() const = 0;
+ virtual const FDE_CSSLENGTH& GetLetterSpacing() const = 0;
+ virtual const FDE_CSSLENGTH& GetWordSpacing() const = 0;
+ virtual FDE_CSSWRITINGMODE GetWritingMode() const = 0;
+ virtual FDE_CSSWORDBREAK GetWordBreak() const = 0;
+ virtual FX_INT32 GetWidows() const = 0;
+ virtual FX_ARGB GetTextEmphasisColor() const = 0;
+ virtual FDE_CSSPAGEBREAK GetPageBreakBefore() const = 0;
+ virtual FDE_CSSPAGEBREAK GetPageBreakAfter() const = 0;
+ virtual FDE_CSSPAGEBREAK GetPageBreakInside() const = 0;
+ virtual FX_INT32 GetOrphans() const = 0;
+ virtual FDE_CSSLINEBREAK GetLineBreak() const = 0;
+ virtual FDE_CSSTEXTEMPHASISMARK GetTextEmphasisMark() const = 0;
+ virtual FDE_CSSTEXTEMPHASISFILL GetTextEmphasisFill() const = 0;
+ virtual FX_LPCWSTR GetTextEmphasisCustom() const = 0;
+ virtual FDE_CSSTEXTCOMBINE GetTextCombineType() const = 0;
+ virtual FX_BOOL HasTextCombineNumber() const = 0;
+ virtual FX_FLOAT GetTextCombineNumber() const = 0;
+ virtual void SetLineHeight(FX_FLOAT fLineHeight) = 0;
+ virtual void SetWhiteSpace(FDE_CSSWHITESPACE eWhiteSpace) = 0;
+ virtual void SetTextIndent(const FDE_CSSLENGTH &textIndent) = 0;
+ virtual void SetTextAlign(FDE_CSSTEXTALIGN eTextAlign) = 0;
+ virtual void SetVerticalAlign(FDE_CSSVERTICALALIGN eVerticalAlign) = 0;
+ virtual void SetNumberVerticalAlign(FX_FLOAT fAlign) = 0;
+ virtual void SetTextTransform(FDE_CSSTEXTTRANSFORM eTextTransform) = 0;
+ virtual void SetTextDecoration(FX_DWORD dwTextDecoration) = 0;
+ virtual void SetLetterSpacing(const FDE_CSSLENGTH &letterSpacing) = 0;
+ virtual void SetWordSpacing(const FDE_CSSLENGTH &wordSpacing) = 0;
+ virtual void SetWritingMode(FDE_CSSWRITINGMODE eWritingMode) = 0;
+ virtual void SetWordBreak(FDE_CSSWORDBREAK eWordBreak) = 0;
+ virtual void SetWidows(FX_INT32 iWidows) = 0;
+ virtual void SetTextEmphasisColor(FX_ARGB dwTextEmphasisColor) = 0;
+ virtual void SetPageBreakBefore(FDE_CSSPAGEBREAK ePageBreakBefore) = 0;
+ virtual void SetPageBreakAfter(FDE_CSSPAGEBREAK ePageBreakAfter) = 0;
+ virtual void SetPageBreakInside(FDE_CSSPAGEBREAK ePageBreakInside) = 0;
+ virtual void SetOrphans(FX_INT32 iOrphans) = 0;
+ virtual void SetLineBreak(FDE_CSSLINEBREAK eLineBreak) = 0;
+};
+class IFDE_CSSBackgroundStyle
+{
+public:
+ virtual FX_ARGB GetBKGColor() const = 0;
+ virtual FX_LPCWSTR GetBKGImage() const = 0;
+ virtual FDE_CSSBKGREPEAT GetBKGRepeat() const = 0;
+ virtual FDE_CSSBKGATTACHMENT GetBKGAttachment() const = 0;
+ virtual const FDE_CSSPOINT& GetBKGPosition() const = 0;
+ virtual void SetBKGColor(FX_ARGB dwBKGColor) = 0;
+ virtual void SetBKGPosition(const FDE_CSSPOINT &bkgPosition) = 0;
+};
+class IFDE_CSSListStyle
+{
+public:
+ virtual FDE_CSSLISTSTYLETYPE GetListStyleType() const = 0;
+ virtual FDE_CSSLISTSTYLEPOSITION GetListStylePosition() const = 0;
+ virtual FX_LPCWSTR GetListStyleImage() const = 0;
+ virtual void SetListStyleType(FDE_CSSLISTSTYLETYPE eListStyleType) = 0;
+ virtual void SetListStylePosition(FDE_CSSLISTSTYLEPOSITION eListStylePosition) = 0;
+};
+class IFDE_CSSTableStyle
+{
+public:
+ virtual FDE_CSSCAPTIONSIDE GetCaptionSide() const = 0;
+};
+class IFDE_CSSVisualStyle
+{
+public:
+ virtual FDE_CSSVISIBILITY GetVisibility() const = 0;
+ virtual FDE_CSSOVERFLOW GetOverflowX() const = 0;
+ virtual FDE_CSSOVERFLOW GetOverflowY() const = 0;
+ virtual void SetVisibility(FDE_CSSVISIBILITY eVisibility) = 0;
+};
+class IFDE_CSSComputedStyle : public IFX_Unknown
+{
+public:
+ virtual void Reset() = 0;
+ virtual IFDE_CSSFontStyle* GetFontStyles() const = 0;
+ virtual IFDE_CSSBoundaryStyle* GetBoundaryStyles() const = 0;
+ virtual IFDE_CSSPositionStyle* GetPositionStyles() const = 0;
+ virtual IFDE_CSSParagraphStyle* GetParagraphStyles() const = 0;
+ virtual IFDE_CSSBackgroundStyle* GetBackgroundStyles() const = 0;
+ virtual IFDE_CSSVisualStyle* GetVisualStyles() const = 0;
+ virtual IFDE_CSSListStyle* GetListStyles() const = 0;
+ virtual IFDE_CSSMultiColumnStyle* GetMultiColumnStyle() const = 0;
+ virtual IFDE_CSSTableStyle* GetTableStyle() const = 0;
+ virtual IFDE_CSSGeneratedContentStyle* GetGeneratedContentStyle() const = 0;
+ virtual IFDE_CSSRubyStyle* GetRubyStyle() const = 0;
+ virtual FX_BOOL GetCustomStyle(FX_WSTR wsName, CFX_WideString &wsValue) const = 0;
+};
+enum FDE_CSSSTYLESHEETGROUP {
+ FDE_CSSSTYLESHEETGROUP_UserAgent,
+ FDE_CSSSTYLESHEETGROUP_User,
+ FDE_CSSSTYLESHEETGROUP_Author,
+ FDE_CSSSTYLESHEETGROUP_MAX,
+};
+enum FDE_CSSSTYLESHEETPRIORITY {
+ FDE_CSSSTYLESHEETPRIORITY_High,
+ FDE_CSSSTYLESHEETPRIORITY_Mid,
+ FDE_CSSSTYLESHEETPRIORITY_Low,
+ FDE_CSSSTYLESHEETPRIORITY_MAX,
+};
+class IFDE_CSSTagProvider
+{
+public:
+ virtual CFX_WideStringC GetTagName() = 0;
+ virtual FX_POSITION GetFirstAttribute() = 0;
+ virtual void GetNextAttribute(FX_POSITION &pos, CFX_WideStringC &wsAttr, CFX_WideStringC &wsValue) = 0;
+};
+class IFDE_CSSAccelerator
+{
+public:
+ virtual void OnEnterTag(IFDE_CSSTagProvider *pTag) = 0;
+ virtual void OnLeaveTag(IFDE_CSSTagProvider *pTag) = 0;
+};
+class IFDE_CSSStyleSelector
+{
+public:
+ static IFDE_CSSStyleSelector* Create();
+ virtual void Release() = 0;
+ virtual void SetFontMgr(IFX_FontMgr *pFontMgr) = 0;
+ virtual void SetDefFontSize(FX_FLOAT fFontSize) = 0;
+ virtual FX_BOOL SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType, IFDE_CSSStyleSheet *pSheet) = 0;
+ virtual FX_BOOL SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType, const CFDE_CSSStyleSheetArray *pArray) = 0;
+ virtual void SetStylePriority(FDE_CSSSTYLESHEETGROUP eType, FDE_CSSSTYLESHEETPRIORITY ePriority) = 0;
+ virtual void UpdateStyleIndex(FX_DWORD dwMediaList) = 0;
+ virtual IFDE_CSSAccelerator* InitAccelerator() = 0;
+ virtual IFDE_CSSComputedStyle* CreateComputedStyle(IFDE_CSSComputedStyle *pParentStyle) = 0;
+ virtual FX_INT32 MatchDeclarations(IFDE_CSSTagProvider *pTag, CFDE_CSSDeclarationArray &matchedDecls, FDE_CSSPERSUDO ePersudoType = FDE_CSSPERSUDO_NONE) = 0;
+ virtual void ComputeStyle(IFDE_CSSTagProvider *pTag, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_img.h b/xfa/src/fdp/include/fde_img.h
new file mode 100644
index 0000000000..808bc4c304
--- /dev/null
+++ b/xfa/src/fdp/include/fde_img.h
@@ -0,0 +1,76 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_IMAGE
+#define _FDE_IMAGE
+class IFDE_Image;
+#define FDE_IMAGEFORMAT_Unknown -1
+#define FDE_IMAGEFORMAT_BMP 0
+#define FDE_IMAGEFORMAT_GIF 1
+#define FDE_IMAGEFORMAT_JPEG 2
+#define FDE_IMAGEFORMAT_PNG 3
+#define FDE_IMAGEFORMAT_TIFF 4
+#define FDE_IMAGEFORMAT_JPEG2000 5
+#define FDE_IMAGEFORMAT_JBig2 6
+class IFDE_Image
+{
+public:
+ static IFDE_Image* Create(IFX_Stream *pStream, FX_INT32 iFormat = FDE_IMAGEFORMAT_Unknown);
+ virtual void Release() = 0;
+ virtual FX_BOOL LoadImage() = 0;
+ virtual void FreeImage() = 0;
+ virtual FX_INT32 CountFrames() const = 0;
+ virtual FX_BOOL LoadFrame(FX_INT32 index) = 0;
+ virtual CFX_DIBitmap* GetFrameImage() = 0;
+ virtual FX_INT32 GetImageFormat() const = 0;
+ virtual FX_INT32 GetImageWidth() const = 0;
+ virtual FX_INT32 GetImageHeight() const = 0;
+ virtual FX_INT32 GetDelayTime(FX_INT32 iFrameIndex) const = 0;
+ virtual FX_INT32 GetLoopCount() const = 0;
+ virtual FX_BOOL StartLoadImage(CFX_DIBitmap *pDIBitmap, FX_INT32 dibX, FX_INT32 dibY, FX_INT32 dibCX, FX_INT32 dibCY,
+ FX_INT32 imgX, FX_INT32 imgY, FX_INT32 imgCX, FX_INT32 imgCY, FX_INT32 iFrameIndex = 0) = 0;
+ virtual FX_INT32 DoLoadImage(IFX_Pause *pPause = NULL) = 0;
+ virtual void StopLoadImage() = 0;
+};
+#define FDE_IMAGEFILTER_Unknown -1
+#define FDE_IMAGEFILTER_Opacity 0
+#define FDE_IMAGEFILTER_GrayScale 1
+#define FDE_IMAGEFILTER_BlackWhite 2
+#define FDE_IMAGEFILTER_InvertColor 3
+#define FDE_IMAGEFILTER_TransparentColor 4
+#define FDE_IMAGEFILTER_MaskColor 5
+#define FDE_IMAGEFILTER_Brightness 6
+#define FDE_IMAGEFILTER_Contrast 7
+typedef struct _FDE_IMAGEFILTERPARAMS : public CFX_Target {
+ FX_INT32 iFilterType;
+} FDE_IMAGEFILTERPARAMS, * FDE_LPIMAGEFILTERPARAMS;
+typedef FDE_IMAGEFILTERPARAMS const * FDE_LPCIMAGEFILTERPARAMS;
+typedef struct _FDE_OPACITYPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_INT32 iOpacity;
+} FDE_OPACITYPARAMS, * FDE_LPOPACITYPARAMS;
+typedef FDE_OPACITYPARAMS const * FDE_LPCOPACITYPARAMS;
+typedef struct _FDE_BLACKWHITEPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_ARGB dwBlackColor;
+ FX_ARGB dwWhiteColor;
+} FDE_BLACKWHITEPARAMS, * FDE_LPBLACKWHITEPARAMS;
+typedef FDE_BLACKWHITEPARAMS const * FDE_LPCBLACKWHITEPARAMS;
+typedef struct _FDE_TRANSPARENTPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_ARGB color;
+} FDE_TRANSPARENTPARAMS, * FDE_LPTRANSPARENTPARAMS;
+typedef FDE_TRANSPARENTPARAMS const * FDE_LPCTRANSPARENTPARAMS;
+typedef struct _FDE_MASKCOLORPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_ARGB color;
+} FDE_MASKCOLORPARAMS, * FDE_LPMASKCOLORPARAMS;
+typedef FDE_MASKCOLORPARAMS const * FDE_LPCMASKCOLORPARAMS;
+typedef struct _FDE_BRIGHTNESSPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_INT32 iBrightness;
+} FDE_BRIGHTNESSPARAMS, * FDE_LPBRIGHTNESSPARAMS;
+typedef FDE_BRIGHTNESSPARAMS const * FDE_LPCBRIGHTNESSPARAMS;
+typedef struct _FDE_CONTRASTPARAMS : public FDE_IMAGEFILTERPARAMS {
+ FX_INT32 iContrast;
+} FDE_CONTRASTPARAMS, * FDE_LPCONTRASTPARAMS;
+typedef FDE_CONTRASTPARAMS const * FDE_LPCCONTRASTPARAMS;
+#endif
diff --git a/xfa/src/fdp/include/fde_mem.h b/xfa/src/fdp/include/fde_mem.h
new file mode 100644
index 0000000000..516e67c945
--- /dev/null
+++ b/xfa/src/fdp/include/fde_mem.h
@@ -0,0 +1,23 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_MEM
+#define _FDE_MEM
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define FDE_Alloc(size) FX_Alloc(FX_BYTE, size)
+#define FDE_Realloc(ptr, newSize) FX_Realloc(FX_BYTE, ptr, newSize)
+#define FDE_Free(ptr) FX_Free(ptr)
+#define FDE_New FXTARGET_New
+#define FDE_Delete FXTARGET_Delete
+#define FDE_NewWith FXTARGET_NewWith
+#define FDE_DeleteWith FXTARGET_DeleteWith
+
+#ifdef __cplusplus
+};
+#endif
+#endif
diff --git a/xfa/src/fdp/include/fde_pen.h b/xfa/src/fdp/include/fde_pen.h
new file mode 100644
index 0000000000..7730b6a964
--- /dev/null
+++ b/xfa/src/fdp/include/fde_pen.h
@@ -0,0 +1,61 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_PEN
+#define _FDE_PEN
+class IFDE_Pen;
+#define FDE_PENTYPE_Unknown FDE_BRUSHTYPE_Unknown
+#define FDE_PENTYPE_SolidColor FDE_BRUSHTYPE_Solid
+#define FDE_PENTYPE_HatchBrush FDE_BRUSHTYPE_Hatch
+#define FDE_PENTYPE_TextureBrush FDE_BRUSHTYPE_Texture
+#define FDE_PENTYPE_LinearGradient FDE_BRUSHTYPE_LinearGradient
+#define FDE_PENTYPE_MAX FDE_BRUSHTYPE_MAX
+#define FDE_DASHSTYLE_Solid 0
+#define FDE_DASHSTYLE_Dash 1
+#define FDE_DASHSTYLE_Dot 2
+#define FDE_DASHSTYLE_DashDot 3
+#define FDE_DASHSTYLE_DashDotDot 4
+#define FDE_DASHSTYLE_Customized 5
+#define FDE_LINEJOIN_Miter 0
+#define FDE_LINEJOIN_Round 1
+#define FDE_LINEJOIN_Bevel 2
+#define FDE_LINECAP_Flat 0
+#define FDE_LINECAP_Round 1
+#define FDE_LINECAP_Square 2
+typedef struct _FDE_COMPOUNDPATTERN {
+ FX_FLOAT pos;
+ FX_FLOAT width;
+} FDE_COMPOUNDPATTERN, * FDE_LPCOMPOUNDPATTERN;
+typedef FDE_COMPOUNDPATTERN const * FDE_LPCCOMPOUNDPATTERN;
+typedef CFX_ArrayTemplate<FDE_COMPOUNDPATTERN> CFDE_CompoundPatterns;
+class IFDE_Pen
+{
+public:
+ static IFDE_Pen* Create();
+ virtual void Release() = 0;
+ virtual FX_INT32 GetType() const = 0;
+ virtual FX_ARGB GetColor() const = 0;
+ virtual void SetColor(FX_ARGB color) = 0;
+ virtual IFDE_Brush* GetBrush() const = 0;
+ virtual void SetBrush(IFDE_Brush *pBrush, FX_BOOL bAutoRelease) = 0;
+ virtual FX_INT32 GetLineCap() const = 0;
+ virtual void SetLineCap(FX_INT32 iLineCap) = 0;
+ virtual FX_INT32 GetDashStyle() const = 0;
+ virtual void SetDashStyle(FX_INT32 iDashStyle) = 0;
+ virtual FX_FLOAT GetDashPhase() const = 0;
+ virtual void SetDashPhase(FX_FLOAT fPhase) = 0;
+ virtual FX_INT32 CountDashArray() const = 0;
+ virtual FX_INT32 GetDashArray(CFX_FloatArray &dashArray) const = 0;
+ virtual void SetDashArray(const CFX_FloatArray &dashArray) = 0;
+ virtual FX_INT32 GetLineJoin() const = 0;
+ virtual void SetLineJoin(FX_INT32 iLineJoin) = 0;
+ virtual FX_FLOAT GetMiterLimit() const = 0;
+ virtual void SetMiterLimit(FX_FLOAT fMiterLimit) = 0;
+ virtual FX_INT32 CountCompoundPatterns() const = 0;
+ virtual FX_BOOL GetCompoundPatterns(CFDE_CompoundPatterns &compoundPatterns) const = 0;
+ virtual FX_BOOL SetCompoundPatterns(const CFDE_CompoundPatterns &compoundPatterns) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_psr.h b/xfa/src/fdp/include/fde_psr.h
new file mode 100644
index 0000000000..64070e6648
--- /dev/null
+++ b/xfa/src/fdp/include/fde_psr.h
@@ -0,0 +1,94 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_PARSER
+#define _FDE_PARSER
+enum FDE_VISUALOBJTYPE {
+ FDE_VISUALOBJ_Canvas = 0x00,
+ FDE_VISUALOBJ_Text = 0x01 ,
+ FDE_VISUALOBJ_Image = 0x02 ,
+ FDE_VISUALOBJ_Path = 0x04 ,
+ FDE_VISUALOBJ_Widget = 0x08 ,
+};
+typedef struct _FDE_HVISUALOBJ {
+ FX_LPVOID pData;
+} const * FDE_HVISUALOBJ;
+class IFDE_VisualSet
+{
+public:
+ virtual FDE_VISUALOBJTYPE GetType() = 0;
+ virtual FX_BOOL GetBBox(FDE_HVISUALOBJ hVisualObj, CFX_RectF &bbox) = 0;
+ virtual FX_BOOL GetMatrix(FDE_HVISUALOBJ hVisualObj, CFX_Matrix &matrix) = 0;
+ virtual FX_BOOL GetRect(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt) = 0;
+ virtual FX_BOOL GetClip(FDE_HVISUALOBJ hVisualObj, CFX_RectF &rt) = 0;
+};
+class IFDE_CanvasSet : public IFDE_VisualSet
+{
+public:
+ virtual FX_POSITION GetFirstPosition(FDE_HVISUALOBJ hCanvas) = 0;
+ virtual FDE_HVISUALOBJ GetNext(FDE_HVISUALOBJ hCanvas, FX_POSITION &pos, IFDE_VisualSet *&pVisualSet) = 0;
+ virtual FDE_HVISUALOBJ GetParentCanvas(FDE_HVISUALOBJ hCanvas, IFDE_VisualSet *&pVisualSet) = 0;
+};
+class IFDE_TextSet : public IFDE_VisualSet
+{
+public:
+ virtual FX_INT32 GetString(FDE_HVISUALOBJ hText, CFX_WideString &wsText) = 0;
+ virtual IFX_Font* GetFont(FDE_HVISUALOBJ hText) = 0;
+ virtual FX_FLOAT GetFontSize(FDE_HVISUALOBJ hText) = 0;
+ virtual FX_ARGB GetFontColor(FDE_HVISUALOBJ hText) = 0;
+ virtual FX_INT32 GetDisplayPos(FDE_HVISUALOBJ hText, FXTEXT_CHARPOS *pCharPos, FX_BOOL bCharCode = FALSE, CFX_WideString *pWSForms = NULL) = 0;
+ virtual FX_INT32 GetCharRects(FDE_HVISUALOBJ hText, CFX_RectFArray &rtArray) = 0;
+};
+class IFDE_ImageSet : public IFDE_VisualSet
+{
+public:
+ virtual IFDE_Image* GetImage(FDE_HVISUALOBJ hImage) = 0;
+ virtual FX_POSITION GetFirstFilterPosition(FDE_HVISUALOBJ hImage) = 0;
+ virtual FDE_LPCIMAGEFILTERPARAMS GetNextFilter(FDE_HVISUALOBJ hImage, FX_POSITION &pos) = 0;
+};
+#define FDE_FILLMODE_Alternate 1
+#define FDE_FILLMODE_Winding 2
+#define FDE_PATHRENDER_Stroke 1
+#define FDE_PATHRENDER_Fill 2
+#define FDE_PATHRENDER_FillStroke 3
+class IFDE_PathSet : public IFDE_VisualSet
+{
+public:
+ virtual IFDE_Path* GetPath(FDE_HVISUALOBJ hPath) = 0;
+ virtual FX_INT32 GetFillMode(FDE_HVISUALOBJ hPath) = 0;
+ virtual FX_INT32 GetRenderMode(FDE_HVISUALOBJ hPath) = 0;
+ virtual IFDE_Pen* GetPen(FDE_HVISUALOBJ hPath) = 0;
+ virtual FX_FLOAT GetPenWidth(FDE_HVISUALOBJ hPath) = 0;
+ virtual IFDE_Brush* GetBrush(FDE_HVISUALOBJ hPath) = 0;
+};
+enum FDE_WIDGETOBJ {
+ FDE_WIDGETOBJ_Unknown = 0x0000,
+ FDE_WIDGETOBJ_Anchor = 0x0100,
+ FDE_WIDGETOBJ_NamedDest = 0x0200,
+ FDE_WIDGETOBJ_HyperLink = 0x0400,
+};
+#define FDE_WIDGETPARAM_Uri 1
+#define FDE_WIDGETPARAM_Rects 2
+class IFDE_WidgetSet : public IFDE_VisualSet
+{
+public:
+ virtual FDE_WIDGETOBJ GetWidgetType(FDE_HVISUALOBJ hWidget) = 0;
+ virtual FX_FLOAT GetFloat(FDE_HVISUALOBJ hWidget, FX_INT32 iParameter, FX_FLOAT fDefVal = 0.0f) = 0;
+ virtual FX_INT32 GetInteger(FDE_HVISUALOBJ hWidget, FX_INT32 iParameter, FX_INT32 iDefVal = 0) = 0;
+ virtual FX_BOOL GetString(FDE_HVISUALOBJ hWidget, FX_INT32 iParameter, CFX_WideString &wsValue) = 0;
+ virtual FX_BOOL GetRects(FDE_HVISUALOBJ hWidget, FX_INT32 iParameter, CFX_RectFArray &rects) = 0;
+};
+class IFDE_VisualSetIterator
+{
+public:
+ static IFDE_VisualSetIterator* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL AttachCanvas(IFDE_CanvasSet *pCanvas) = 0;
+ virtual FX_BOOL FilterObjects(FX_DWORD dwObjects = 0xFFFFFFFF) = 0;
+ virtual void Reset() = 0;
+ virtual FDE_HVISUALOBJ GetNext(IFDE_VisualSet *&pVisualSet, FDE_HVISUALOBJ *phCanvasObj = NULL, IFDE_CanvasSet **ppCanvasSet = NULL) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_pth.h b/xfa/src/fdp/include/fde_pth.h
new file mode 100644
index 0000000000..be3cc8d50e
--- /dev/null
+++ b/xfa/src/fdp/include/fde_pth.h
@@ -0,0 +1,29 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_PATH
+#define _FDE_PATH
+class IFDE_Path;
+class IFDE_Path
+{
+public:
+ static IFDE_Path* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL StartFigure() = 0;
+ virtual FX_BOOL CloseFigure() = 0;
+ virtual void AddBezier(const CFX_PointsF &points) = 0;
+ virtual void AddBeziers(const CFX_PointsF &points) = 0;
+ virtual void AddCurve(const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f) = 0;
+ virtual void AddEllipse(const CFX_RectF &rect) = 0;
+ virtual void AddLines(const CFX_PointsF &points) = 0;
+ virtual void AddLine(const CFX_PointF &pt1, const CFX_PointF &pt2) = 0;
+ virtual void AddPath(const IFDE_Path *pSrc, FX_BOOL bConnect) = 0;
+ virtual void AddPolygon(const CFX_PointsF &points) = 0;
+ virtual void AddRectangle(const CFX_RectF &rect) = 0;
+ virtual void GetBBox(CFX_RectF &bbox) const = 0;
+ virtual void GetBBox(CFX_RectF &bbox, FX_FLOAT fLineWidth, FX_FLOAT fMiterLimit) const = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_rdr.h b/xfa/src/fdp/include/fde_rdr.h
new file mode 100644
index 0000000000..74c5d24516
--- /dev/null
+++ b/xfa/src/fdp/include/fde_rdr.h
@@ -0,0 +1,32 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_RENDERCONTEXT
+#define _FDE_RENDERCONTEXT
+class IFDE_Page;
+class IFDE_RenderDevice;
+class IFDE_RenderContext;
+void FDE_GetPageMatrix(CFX_Matrix &pageMatrix, const CFX_RectF &docPageRect, const CFX_Rect &devicePageRect, FX_INT32 iRotate, FX_DWORD dwCoordinatesType = 0);
+enum FDE_RENDERSTATUS {
+ FDE_RENDERSTATUS_Reset = 0,
+ FDE_RENDERSTATUS_Paused ,
+ FDE_RENDERSTATUS_Done ,
+ FDE_RENDERSTATUS_Failed ,
+};
+class IFDE_RenderContext
+{
+public:
+ static IFDE_RenderContext* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL StartRender(IFDE_RenderDevice *pRenderDevice,
+ IFDE_CanvasSet *pCanvasSet,
+ const CFX_Matrix &tmDoc2Device
+ ) = 0;
+ virtual FDE_RENDERSTATUS GetStatus() const = 0;
+ virtual FDE_RENDERSTATUS DoRender(IFX_Pause *pPause = NULL) = 0;
+ virtual void StopRender() = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_rdv.h b/xfa/src/fdp/include/fde_rdv.h
new file mode 100644
index 0000000000..ee1e922c48
--- /dev/null
+++ b/xfa/src/fdp/include/fde_rdv.h
@@ -0,0 +1,53 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_RENDERDEVICE
+#define _FDE_RENDERDEVICE
+class IFDE_Pen;
+class IFDE_Brush;
+class IFDE_Image;
+class CFX_DIBitmap;
+class CFX_DIBSource;
+class IFDE_RenderDevice;
+typedef struct _FDE_HDEVICESTATE {
+ FX_LPVOID pData;
+} * FDE_HDEVICESTATE;
+class IFDE_RenderDevice
+{
+public:
+ static IFDE_RenderDevice* Create(CFX_DIBitmap *pBitmap, FX_BOOL bRgbByteOrder = FALSE);
+ static IFDE_RenderDevice* Create(CFX_RenderDevice *pDevice);
+ virtual void Release() = 0;
+
+ virtual FX_INT32 GetWidth() const = 0;
+ virtual FX_INT32 GetHeight() const = 0;
+ virtual FDE_HDEVICESTATE SaveState() = 0;
+ virtual void RestoreState(FDE_HDEVICESTATE hState) = 0;
+ virtual FX_BOOL SetClipPath(const IFDE_Path *pClip) = 0;
+ virtual IFDE_Path* GetClipPath() const = 0;
+ virtual FX_BOOL SetClipRect(const CFX_RectF &rtClip) = 0;
+ virtual const CFX_RectF& GetClipRect() = 0;
+
+ virtual FX_FLOAT GetDpiX() const = 0;
+ virtual FX_FLOAT GetDpiY() const = 0;
+
+ virtual FX_BOOL DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix = NULL, const CFX_Matrix *pDevMatrix = NULL) = 0;
+ virtual FX_BOOL DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL) = 0;
+ virtual FX_BOOL FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL) = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_tto.h b/xfa/src/fdp/include/fde_tto.h
new file mode 100644
index 0000000000..25dead13ca
--- /dev/null
+++ b/xfa/src/fdp/include/fde_tto.h
@@ -0,0 +1,69 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_TEXTOUT
+#define _FDE_TEXTOUT
+class IFDE_TextOut;
+#define FDE_TTOSTYLE_Underline 0x0001
+#define FDE_TTOSTYLE_Strikeout 0x0002
+#define FDE_TTOSTYLE_VerticalLayout 0x0004
+#define FDE_TTOSTYLE_SingleLine 0x0010
+#define FDE_TTOSTYLE_ExpandTab 0x0020
+#define FDE_TTOSTYLE_HotKey 0x0040
+#define FDE_TTOSTYLE_Ellipsis 0x0080
+#define FDE_TTOSTYLE_LineWrap 0x0100
+#define FDE_TTOSTYLE_ArabicShapes 0x0200
+#define FDE_TTOSTYLE_RTL 0x0400
+#define FDE_TTOSTYLE_ArabicContext 0x0800
+#define FDE_TTOSTYLE_LastLineHeight 0x1000
+#define FDE_TTOALIGNMENT_TopLeft 0
+#define FDE_TTOALIGNMENT_TopCenter 1
+#define FDE_TTOALIGNMENT_TopRight 2
+#define FDE_TTOALIGNMENT_TopAuto 3
+#define FDE_TTOALIGNMENT_CenterLeft 4
+#define FDE_TTOALIGNMENT_Center 5
+#define FDE_TTOALIGNMENT_CenterRight 6
+#define FDE_TTOALIGNMENT_CenterAuto 7
+#define FDE_TTOALIGNMENT_BottomLeft 8
+#define FDE_TTOALIGNMENT_BottomCenter 9
+#define FDE_TTOALIGNMENT_BottomRight 10
+#define FDE_TTOALIGNMENT_BottomAuto 11
+class IFDE_TextOut
+{
+public:
+ static IFDE_TextOut* Create();
+ virtual void Release() = 0;
+ virtual void SetFont(IFX_Font *pFont) = 0;
+ virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
+ virtual void SetTextColor(FX_ARGB color) = 0;
+ virtual void SetStyles(FX_DWORD dwStyles) = 0;
+ virtual void SetTabWidth(FX_FLOAT fTabWidth) = 0;
+ virtual void SetEllipsisString(const CFX_WideString &wsEllipsis) = 0;
+ virtual void SetParagraphBreakChar(FX_WCHAR wch) = 0;
+ virtual void SetAlignment(FX_INT32 iAlignment) = 0;
+ virtual void SetLineSpace(FX_FLOAT fLineSpace) = 0;
+ virtual void SetDIBitmap(CFX_DIBitmap *pDIB) = 0;
+ virtual void SetRenderDevice(CFX_RenderDevice *pDevice) = 0;
+ virtual void SetClipRect(const CFX_Rect &rtClip) = 0;
+ virtual void SetClipRect(const CFX_RectF &rtClip) = 0;
+ virtual void SetMatrix(const CFX_Matrix &matrix) = 0;
+ virtual void SetLineBreakTolerance(FX_FLOAT fTolerance) = 0;
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Size &size) = 0;
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size) = 0;
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Rect &rect) = 0;
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect) = 0;
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_INT32 x, FX_INT32 y) = 0;
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y) = 0;
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_Rect &rect) = 0;
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect) = 0;
+ virtual void SetLogicClipRect(const CFX_RectF &rtClip) = 0;
+ virtual void CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size) = 0;
+ virtual void CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect) = 0;
+ virtual void DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y) = 0;
+ virtual void DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect) = 0;
+ virtual FX_INT32 GetTotalLines() = 0;
+};
+#endif
diff --git a/xfa/src/fdp/include/fde_xml.h b/xfa/src/fdp/include/fde_xml.h
new file mode 100644
index 0000000000..b8b136b5aa
--- /dev/null
+++ b/xfa/src/fdp/include/fde_xml.h
@@ -0,0 +1,188 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_XML
+#define _FDE_XML
+class IFDE_XMLNode;
+class IFDE_XMLInstruction;
+class IFDE_XMLDeclaration;
+class IFDE_XMLDeclComment;
+class IFDE_XMLDeclCharData;
+class IFDE_XMLDeclDocType;
+class IFDE_XMLDeclElement;
+class IFDE_XMLDeclAttriList;
+class IFDE_XMLDeclNotition;
+class IFDE_XMLDeclEntity;
+class IFDE_XMLElement;
+class IFDE_XMLText;
+class IFDE_XMLDoc;
+class IFDE_XMLParser;
+class IFDE_XMLSyntaxParser;
+#ifdef __cplusplus
+extern "C" {
+#endif
+enum FDE_XMLNODETYPE {
+ FDE_XMLNODE_Unknown = 0,
+ FDE_XMLNODE_Instruction ,
+ FDE_XMLNODE_Element ,
+ FDE_XMLNODE_Text ,
+ FDE_XMLNODE_CharData ,
+};
+typedef struct _FDE_XMLNODE {
+ FX_INT32 iNodeNum;
+ FDE_XMLNODETYPE eNodeType;
+} FDE_XMLNODE, * FDE_LPXMLNODE;
+typedef FDE_XMLNODE const * FDE_LPCXMLNODE;
+typedef CFX_StackTemplate<FDE_XMLNODE> CFDE_XMLNodeStack;
+FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch);
+FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch);
+FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar);
+#ifdef __cplusplus
+}
+#endif
+class IFDE_XMLNode
+{
+public:
+ virtual void Release() = 0;
+ virtual FDE_XMLNODETYPE GetType() const = 0;
+ virtual FX_INT32 CountChildNodes() const = 0;
+ virtual IFDE_XMLNode* GetChildNode(FX_INT32 index) const = 0;
+ virtual FX_INT32 GetChildNodeIndex(IFDE_XMLNode *pNode) const = 0;
+ virtual IFDE_XMLNode* GetPath(FX_LPCWSTR pPath, FX_INT32 iLength = -1, FX_BOOL bQualifiedName = TRUE) const = 0;
+ virtual FX_INT32 InsertChildNode(IFDE_XMLNode *pNode, FX_INT32 index = -1) = 0;
+ virtual void RemoveChildNode(IFDE_XMLNode *pNode) = 0;
+ virtual void DeleteChildren() = 0;
+ enum NodeItem {Root = 0, Parent, FirstSibling, PriorSibling, NextSibling, LastSibling, FirstNeighbor, PriorNeighbor, NextNeighbor, LastNeighbor, FirstChild, LastChild};
+ virtual IFDE_XMLNode* GetNodeItem(NodeItem eItem) const = 0;
+ virtual FX_INT32 GetNodeLevel() const = 0;
+ virtual FX_BOOL InsertNodeItem(IFDE_XMLNode::NodeItem eItem, IFDE_XMLNode *pNode) = 0;
+ virtual IFDE_XMLNode* RemoveNodeItem(IFDE_XMLNode::NodeItem eItem) = 0;
+ virtual IFDE_XMLNode* Clone(FX_BOOL bRecursive) = 0;
+ virtual void SaveXMLNode(IFX_Stream *pXMLStream) = 0;
+};
+class IFDE_XMLInstruction : public IFDE_XMLNode
+{
+public:
+ static IFDE_XMLInstruction* Create(const CFX_WideString &wsTarget);
+ virtual void GetTargetName(CFX_WideString &wsTarget) const = 0;
+ virtual FX_INT32 CountAttributes() const = 0;
+ virtual FX_BOOL GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const = 0;
+ virtual FX_BOOL HasAttribute(FX_LPCWSTR pwsAttriName) const = 0;
+ virtual void GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue = NULL) const = 0;
+ virtual void SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue) = 0;
+ virtual FX_INT32 GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue = 0) const = 0;
+ virtual void SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue) = 0;
+ virtual FX_FLOAT GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue = 0) const = 0;
+ virtual void SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue) = 0;
+ virtual void RemoveAttribute(FX_LPCWSTR pwsAttriName) = 0;
+ virtual FX_INT32 CountData() const = 0;
+ virtual FX_BOOL GetData(FX_INT32 index, CFX_WideString &wsData) const = 0;
+ virtual void AppendData(const CFX_WideString &wsData) = 0;
+ virtual void RemoveData(FX_INT32 index) = 0;
+};
+class IFDE_XMLElement : public IFDE_XMLNode
+{
+public:
+ static IFDE_XMLElement* Create(const CFX_WideString &wsTag);
+ virtual void GetTagName(CFX_WideString &wsTag) const = 0;
+ virtual void GetLocalTagName(CFX_WideString &wsTag) const = 0;
+ virtual void GetNamespacePrefix(CFX_WideString &wsPrefix) const = 0;
+ virtual void GetNamespaceURI(CFX_WideString &wsNamespace) const = 0;
+ virtual FX_INT32 CountAttributes() const = 0;
+ virtual FX_BOOL GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const = 0;
+ virtual FX_BOOL HasAttribute(FX_LPCWSTR pwsAttriName) const = 0;
+ virtual void GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue = NULL) const = 0;
+ virtual void SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue) = 0;
+ virtual FX_INT32 GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue = 0) const = 0;
+ virtual void SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue) = 0;
+ virtual FX_FLOAT GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue = 0) const = 0;
+ virtual void SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue) = 0;
+ virtual void RemoveAttribute(FX_LPCWSTR pwsAttriName) = 0;
+ virtual void GetTextData(CFX_WideString &wsText) const = 0;
+ virtual void SetTextData(const CFX_WideString &wsText) = 0;
+};
+class IFDE_XMLText : public IFDE_XMLNode
+{
+public:
+ static IFDE_XMLText* Create(const CFX_WideString &wsText);
+ virtual void GetText(CFX_WideString &wsText) const = 0;
+ virtual void SetText(const CFX_WideString &wsText) = 0;
+};
+class IFDE_XMLDeclaration : public IFDE_XMLNode
+{
+public:
+};
+class IFDE_XMLCharData : public IFDE_XMLDeclaration
+{
+public:
+ static IFDE_XMLCharData* Create(const CFX_WideString &wsCData);
+
+ virtual void GetCharData(CFX_WideString &wsCData) const = 0;
+ virtual void SetCharData(const CFX_WideString &wsCData) = 0;
+};
+typedef struct _FDE_XMLREADERHANDLER {
+ FX_LPVOID pData;
+
+ void (*OnTagEnter)(_FDE_XMLREADERHANDLER *pThis, FDE_XMLNODETYPE eType, const CFX_WideString &wsTagName);
+ void (*OnTagBreak)(_FDE_XMLREADERHANDLER *pThis, const CFX_WideString &wsTagName);
+ void (*OnTagClose)(_FDE_XMLREADERHANDLER *pThis, const CFX_WideString &wsTagName);
+ void (*OnAttribute)(_FDE_XMLREADERHANDLER *pThis, const CFX_WideString &wsName, const CFX_WideString &wsValue);
+ void (*OnData)(_FDE_XMLREADERHANDLER *pThis, FDE_XMLNODETYPE eType, const CFX_WideString &wsValue);
+} FDE_XMLREADERHANDLER, * FDE_LPXMLREADERHANDLER;
+class IFDE_XMLDoc
+{
+public:
+ static IFDE_XMLDoc* Create();
+ virtual void Release() = 0;
+ virtual FX_BOOL LoadXML(IFX_Stream *pXMLStream, FX_INT32 iXMLPlaneSize = 8192, FX_INT32 iTextDataSize = 256, FDE_LPXMLREADERHANDLER pHandler = NULL) = 0;
+ virtual FX_BOOL LoadXML(IFDE_XMLParser *pXMLParser) = 0;
+ virtual FX_INT32 DoLoad(IFX_Pause *pPause = NULL) = 0;
+ virtual void CloseXML() = 0;
+ virtual IFDE_XMLNode* GetRoot() const = 0;
+ virtual void SaveXML(IFX_Stream *pXMLStream = NULL, FX_BOOL bSaveBOM = TRUE) = 0;
+ virtual void SaveXMLNode(IFX_Stream *pXMLStream, IFDE_XMLNode *pNode) = 0;
+};
+class IFDE_XMLParser
+{
+public:
+ virtual void Release() = 0;
+ virtual FX_INT32 DoParser(IFX_Pause *pPause) = 0;
+};
+#define FDE_XMLSYNTAXSTATUS_None 0x00
+#define FDE_XMLSYNTAXSTATUS_InstructionOpen 0x01
+#define FDE_XMLSYNTAXSTATUS_InstructionClose 0x02
+#define FDE_XMLSYNTAXSTATUS_ElementOpen 0x03
+#define FDE_XMLSYNTAXSTATUS_ElementBreak 0x04
+#define FDE_XMLSYNTAXSTATUS_ElementClose 0x05
+#define FDE_XMLSYNTAXSTATUS_TargetName 0x06
+#define FDE_XMLSYNTAXSTATUS_TagName 0x07
+#define FDE_XMLSYNTAXSTATUS_AttriName 0x08
+#define FDE_XMLSYNTAXSTATUS_AttriValue 0x09
+#define FDE_XMLSYNTAXSTATUS_Text 0x0A
+#define FDE_XMLSYNTAXSTATUS_CData 0x0B
+#define FDE_XMLSYNTAXSTATUS_TargetData 0x0C
+#define FDE_XMLSYNTAXSTATUS_Error 0xFE
+#define FDE_XMLSYNTAXSTATUS_EOS 0xFF
+class IFDE_XMLSyntaxParser
+{
+public:
+ static IFDE_XMLSyntaxParser* Create();
+ virtual void Release() = 0;
+ virtual void Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize = 256) = 0;
+ virtual FX_DWORD DoSyntaxParse() = 0;
+ virtual FX_INT32 GetStatus() const = 0;
+ virtual FX_INT32 GetCurrentPos() const = 0;
+ virtual FX_FILESIZE GetCurrentBinaryPos() const = 0;
+ virtual FX_INT32 GetCurrentNodeNumber() const = 0;
+ virtual FX_INT32 GetLastNodeNumber() const = 0;
+ virtual void GetTargetName(CFX_WideString &wsTarget) const = 0;
+ virtual void GetTagName(CFX_WideString &wsTag) const = 0;
+ virtual void GetAttributeName(CFX_WideString &wsAttriName) const = 0;
+ virtual void GetAttributeValue(CFX_WideString &wsAttriValue) const = 0;
+ virtual void GetTextData(CFX_WideString &wsText) const = 0;
+ virtual void GetTargetData(CFX_WideString &wsData) const = 0;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_csscache.cpp b/xfa/src/fdp/src/css/fde_csscache.cpp
new file mode 100644
index 0000000000..13ff27b8e7
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_csscache.cpp
@@ -0,0 +1,163 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_csscache.h"
+_FDE_CSSCACHEITEM::_FDE_CSSCACHEITEM(IFDE_CSSStyleSheet *p)
+ : pStylesheet(p)
+ , dwActivity(0)
+{
+ FXSYS_assert(pStylesheet);
+ pStylesheet->AddRef();
+}
+_FDE_CSSCACHEITEM::~_FDE_CSSCACHEITEM()
+{
+ pStylesheet->Release();
+}
+IFDE_CSSStyleSheetCache* IFDE_CSSStyleSheetCache::Create()
+{
+ return FDE_New CFDE_CSSStyleSheetCache;
+}
+CFDE_CSSStyleSheetCache::CFDE_CSSStyleSheetCache()
+ : m_pFixedStore(NULL)
+ , m_iMaxItems(5)
+{
+}
+CFDE_CSSStyleSheetCache::~CFDE_CSSStyleSheetCache()
+{
+ FX_POSITION pos = m_Stylesheets.GetStartPosition();
+ if (pos != NULL) {
+ CFX_ByteString szKey;
+ FX_LPVOID pValue;
+ while (pos != NULL) {
+ m_Stylesheets.GetNextAssoc(pos, szKey, pValue);
+ FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, (FDE_LPCSSCACHEITEM)pValue);
+ }
+ m_Stylesheets.RemoveAll();
+ }
+ if (m_pFixedStore != NULL) {
+ m_pFixedStore->Release();
+ }
+}
+void CFDE_CSSStyleSheetCache::AddStyleSheet(FX_BSTR szKey, IFDE_CSSStyleSheet *pStyleSheet)
+{
+ FXSYS_assert(pStyleSheet != NULL);
+ if (m_pFixedStore == NULL) {
+ m_pFixedStore = FX_CreateAllocator(FX_ALLOCTYPE_Fixed, FX_MAX(10, m_iMaxItems), sizeof(FDE_CSSCACHEITEM));
+ FXSYS_assert(m_pFixedStore != NULL);
+ }
+ FX_LPVOID pValue = NULL;
+ if (m_Stylesheets.Lookup(szKey, pValue)) {
+ FDE_LPCSSCACHEITEM pItem = (FDE_LPCSSCACHEITEM)pValue;
+ if (pItem->pStylesheet != pStyleSheet) {
+ pItem->pStylesheet->Release();
+ pItem->pStylesheet = pStyleSheet;
+ pItem->pStylesheet->AddRef();
+ pItem->dwActivity = 0;
+ }
+ } else {
+ while (m_Stylesheets.GetCount() >= m_iMaxItems) {
+ RemoveLowestActivityItem();
+ }
+ FDE_LPCSSCACHEITEM pItem = FDE_NewWith(m_pFixedStore) FDE_CSSCACHEITEM(pStyleSheet);
+ FXSYS_assert(pItem != NULL);
+ m_Stylesheets.SetAt(szKey, pItem);
+ }
+}
+IFDE_CSSStyleSheet* CFDE_CSSStyleSheetCache::GetStyleSheet(FX_BSTR szKey) const
+{
+ FX_LPVOID pValue = NULL;
+ if (m_Stylesheets.Lookup(szKey, pValue)) {
+ FDE_LPCSSCACHEITEM pItem = (FDE_LPCSSCACHEITEM)pValue;
+ pItem->dwActivity++;
+ pItem->pStylesheet->AddRef();
+ return pItem->pStylesheet;
+ }
+ return NULL;
+}
+void CFDE_CSSStyleSheetCache::RemoveStyleSheet(FX_BSTR szKey)
+{
+ FX_LPVOID pValue = NULL;
+ if (!m_Stylesheets.Lookup(szKey, pValue)) {
+ return;
+ }
+ FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, (FDE_LPCSSCACHEITEM)pValue);
+ m_Stylesheets.RemoveKey(szKey);
+}
+void CFDE_CSSStyleSheetCache::RemoveLowestActivityItem()
+{
+ FX_POSITION pos = m_Stylesheets.GetStartPosition();
+ CFX_ByteString szKey;
+ FX_LPVOID pValue;
+ FDE_LPCSSCACHEITEM pItem = NULL;
+ CFX_ByteString szItem;
+ while (pos != NULL) {
+ m_Stylesheets.GetNextAssoc(pos, szKey, pValue);
+ switch (szKey.GetID()) {
+ case FXBSTR_ID('#', 'U', 'S', 'E'):
+ case FXBSTR_ID('#', 'A', 'G', 'E'):
+ continue;
+ }
+ FDE_LPCSSCACHEITEM p = (FDE_LPCSSCACHEITEM)pValue;
+ if (pItem == NULL || pItem->dwActivity > p->dwActivity) {
+ szItem = szKey;
+ pItem = p;
+ }
+ }
+ if (pItem != NULL) {
+ FDE_DeleteWith(FDE_CSSCACHEITEM, m_pFixedStore, pItem);
+ m_Stylesheets.RemoveKey(szItem);
+ }
+}
+_FDE_CSSTAGCACHE::_FDE_CSSTAGCACHE(_FDE_CSSTAGCACHE *parent, IFDE_CSSTagProvider *tag)
+ : pTag(tag)
+ , pParent(parent)
+ , dwIDHash(0)
+ , dwTagHash(0)
+ , iClassIndex(0)
+ , dwClassHashs(1)
+{
+ FXSYS_assert(pTag != NULL);
+ CFX_WideStringC wsValue, wsName = pTag->GetTagName();
+ dwTagHash = FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength(), TRUE);
+ FX_POSITION pos = pTag->GetFirstAttribute();
+ while (pos != NULL) {
+ pTag->GetNextAttribute(pos, wsName, wsValue);
+ FX_DWORD dwNameHash = FX_HashCode_String_GetW(wsName.GetPtr(), wsName.GetLength(), TRUE);
+ static const FX_DWORD s_dwIDHash = FX_HashCode_String_GetW((FX_LPCWSTR)L"id", 2, TRUE);
+ static const FX_DWORD s_dwClassHash = FX_HashCode_String_GetW((FX_LPCWSTR)L"class", 5, TRUE);
+ if (dwNameHash == s_dwClassHash) {
+ FX_DWORD dwHash = FX_HashCode_String_GetW(wsValue.GetPtr(), wsValue.GetLength());
+ dwClassHashs.Add(dwHash);
+ } else if (dwNameHash == s_dwIDHash) {
+ dwIDHash = FX_HashCode_String_GetW(wsValue.GetPtr(), wsValue.GetLength());
+ }
+ }
+}
+_FDE_CSSTAGCACHE::_FDE_CSSTAGCACHE(const _FDE_CSSTAGCACHE &it)
+ : pTag(it.pTag)
+ , pParent(it.pParent)
+ , dwIDHash(it.dwIDHash)
+ , dwTagHash(it.dwTagHash)
+ , iClassIndex(0)
+ , dwClassHashs(1)
+{
+ if (it.dwClassHashs.GetSize() > 0) {
+ dwClassHashs.Copy(it.dwClassHashs);
+ }
+}
+void CFDE_CSSAccelerator::OnEnterTag(IFDE_CSSTagProvider *pTag)
+{
+ FDE_CSSTAGCACHE *pTop = GetTopElement();
+ FDE_CSSTAGCACHE item(pTop, pTag);
+ m_Stack.Push(item);
+}
+void CFDE_CSSAccelerator::OnLeaveTag(IFDE_CSSTagProvider *pTag)
+{
+ FDE_CSSTAGCACHE *pItem = m_Stack.GetTopElement();
+ FXSYS_assert(pItem && pItem->GetTag() == pTag);
+ m_Stack.Pop();
+}
diff --git a/xfa/src/fdp/src/css/fde_csscache.h b/xfa/src/fdp/src/css/fde_csscache.h
new file mode 100644
index 0000000000..f4b8cffd57
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_csscache.h
@@ -0,0 +1,97 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSCACHE
+#define _FDE_CSSCACHE
+typedef struct _FDE_CSSCACHEITEM : public CFX_Target {
+ _FDE_CSSCACHEITEM(IFDE_CSSStyleSheet *p);
+ ~_FDE_CSSCACHEITEM();
+ IFDE_CSSStyleSheet *pStylesheet;
+ FX_DWORD dwActivity;
+} FDE_CSSCACHEITEM, * FDE_LPCSSCACHEITEM;
+class CFDE_CSSStyleSheetCache : public IFDE_CSSStyleSheetCache, public CFX_ThreadLock, public CFX_Target
+{
+public:
+ CFDE_CSSStyleSheetCache();
+ ~CFDE_CSSStyleSheetCache();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual void SetMaxItems(FX_INT32 iMaxCount = 5)
+ {
+ FXSYS_assert(iMaxCount >= 3);
+ m_iMaxItems = iMaxCount;
+ }
+
+ virtual void AddStyleSheet(FX_BSTR szKey, IFDE_CSSStyleSheet *pStyleSheet);
+ virtual IFDE_CSSStyleSheet* GetStyleSheet(FX_BSTR szKey) const;
+ virtual void RemoveStyleSheet(FX_BSTR szKey);
+protected:
+ void RemoveLowestActivityItem();
+ CFX_MapByteStringToPtr m_Stylesheets;
+ IFX_MEMAllocator *m_pFixedStore;
+ FX_INT32 m_iMaxItems;
+};
+typedef struct _FDE_CSSTAGCACHE : public CFX_Target {
+public:
+ _FDE_CSSTAGCACHE(_FDE_CSSTAGCACHE *parent, IFDE_CSSTagProvider *tag);
+ _FDE_CSSTAGCACHE(const _FDE_CSSTAGCACHE &it);
+ _FDE_CSSTAGCACHE* GetParent() const
+ {
+ return pParent;
+ }
+ IFDE_CSSTagProvider* GetTag() const
+ {
+ return pTag;
+ }
+ FX_DWORD HashID() const
+ {
+ return dwIDHash;
+ }
+ FX_DWORD HashTag() const
+ {
+ return dwTagHash;
+ }
+ FX_INT32 CountHashClass() const
+ {
+ return dwClassHashs.GetSize();
+ }
+ void SetClassIndex(FX_INT32 index)
+ {
+ iClassIndex = index;
+ }
+ FX_DWORD HashClass() const
+ {
+ return iClassIndex < dwClassHashs.GetSize() ? dwClassHashs.GetAt(iClassIndex) : 0;
+ }
+protected:
+ IFDE_CSSTagProvider *pTag;
+ _FDE_CSSTAGCACHE *pParent;
+ FX_DWORD dwIDHash;
+ FX_DWORD dwTagHash;
+ FX_INT32 iClassIndex;
+ CFDE_DWordArray dwClassHashs;
+} FDE_CSSTAGCACHE, * FDE_LPCSSTAGCACHE;
+typedef CFX_ObjectStackTemplate<FDE_CSSTAGCACHE> CFDE_CSSTagStack;
+class CFDE_CSSAccelerator : public IFDE_CSSAccelerator, public CFX_Target
+{
+public:
+ virtual void OnEnterTag(IFDE_CSSTagProvider *pTag);
+ virtual void OnLeaveTag(IFDE_CSSTagProvider *pTag);
+ void Clear()
+ {
+ m_Stack.RemoveAll();
+ }
+ FDE_LPCSSTAGCACHE GetTopElement() const
+ {
+ return m_Stack.GetTopElement();
+ }
+protected:
+ CFDE_CSSTagStack m_Stack;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_cssdatatable.cpp b/xfa/src/fdp/src/css/fde_cssdatatable.cpp
new file mode 100644
index 0000000000..b449b27c25
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssdatatable.cpp
@@ -0,0 +1,729 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_cssdatatable.h"
+#ifdef _cplusplus
+extern "C" {
+#endif
+ FX_BOOL FDE_CSSLengthToFloat(const FDE_CSSLENGTH &len, FX_FLOAT fPercentBase, FX_FLOAT &fResult)
+ {
+ switch (len.GetUnit()) {
+ case FDE_CSSLENGTHUNIT_Point:
+ fResult = len.GetValue();
+ return TRUE;
+ case FDE_CSSLENGTHUNIT_Percent:
+ fResult = len.GetValue() * fPercentBase;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ }
+ CFX_FloatRect FDE_CSSBoundaryToRect(IFDE_CSSBoundaryStyle *pBoundStyle, FX_FLOAT fContainerWidth, FX_BOOL bPadding, FX_BOOL bBorder, FX_BOOL bMargin)
+ {
+ FXSYS_assert(pBoundStyle != NULL);
+ FX_FLOAT fResult;
+ const FDE_CSSRECT *pRect;
+ CFX_FloatRect rect(0, 0, 0, 0);
+ if (bPadding) {
+ pRect = pBoundStyle->GetPaddingWidth();
+ if (pRect != NULL) {
+ if (FDE_CSSLengthToFloat(pRect->left, fContainerWidth, fResult)) {
+ rect.left += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->top, fContainerWidth, fResult)) {
+ rect.top += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->right, fContainerWidth, fResult)) {
+ rect.right += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->bottom, fContainerWidth, fResult)) {
+ rect.bottom += fResult;
+ }
+ }
+ }
+ if (bBorder) {
+ pRect = pBoundStyle->GetBorderWidth();
+ if (pRect != NULL) {
+ if (FDE_CSSLengthToFloat(pRect->left, fContainerWidth, fResult)) {
+ rect.left += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->top, fContainerWidth, fResult)) {
+ rect.top += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->right, fContainerWidth, fResult)) {
+ rect.right += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->bottom, fContainerWidth, fResult)) {
+ rect.bottom += fResult;
+ }
+ }
+ }
+ if (bMargin) {
+ pRect = pBoundStyle->GetMarginWidth();
+ if (pRect != NULL) {
+ if (FDE_CSSLengthToFloat(pRect->left, fContainerWidth, fResult)) {
+ rect.left += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->top, fContainerWidth, fResult)) {
+ rect.top += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->right, fContainerWidth, fResult)) {
+ rect.right += fResult;
+ }
+ if (FDE_CSSLengthToFloat(pRect->bottom, fContainerWidth, fResult)) {
+ rect.bottom += fResult;
+ }
+ }
+ }
+ return rect;
+ }
+ FX_DWORD FDE_CSSFontStyleToFDE(IFDE_CSSFontStyle *pFontStyle)
+ {
+ FXSYS_assert(pFontStyle != NULL);
+ FX_DWORD dwFontStyle = FX_FONTSTYLE_Normal;
+ if (pFontStyle->GetFontStyle() == FDE_CSSFONTSTYLE_Italic) {
+ dwFontStyle |= FX_FONTSTYLE_Italic;
+ }
+ if (pFontStyle->GetFontWeight() >= 700) {
+ dwFontStyle |= FX_FONTSTYLE_Bold;
+ }
+ return dwFontStyle;
+ }
+ static const FDE_CSSPROPERTYTABLE g_FDE_CSSProperties[] = {
+ {FDE_CSSPROPERTY_WritingMode, (FX_LPCWSTR)L"writing-mode", 0x01878076, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ColumnRuleWidth, (FX_LPCWSTR)L"column-rule-width", 0x0200FB00, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderLeft, (FX_LPCWSTR)L"border-left", 0x04080036, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_ColumnRule, (FX_LPCWSTR)L"column-rule", 0x04C83DF3, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_Height, (FX_LPCWSTR)L"height", 0x05A5C519, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_CounterReset, (FX_LPCWSTR)L"counter-reset", 0x0894F9B0, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_Content, (FX_LPCWSTR)L"content", 0x097BE91B, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeURI | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_RubyPosition, (FX_LPCWSTR)L"ruby-position", 0x09ACD024, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BackgroundColor, (FX_LPCWSTR)L"background-color", 0x09E8E8AC, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_Width, (FX_LPCWSTR)L"width", 0x0A8A8F80, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Src, (FX_LPCWSTR)L"src", 0x0BD37048, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeURI},
+ {FDE_CSSPROPERTY_Top, (FX_LPCWSTR)L"top", 0x0BEDAF33, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Margin, (FX_LPCWSTR)L"margin", 0x0CB016BE, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderColor, (FX_LPCWSTR)L"border-color", 0x0CBB528A, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_Widows, (FX_LPCWSTR)L"widows", 0x1026C59D, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderBottomColor, (FX_LPCWSTR)L"border-bottom-color", 0x121E22EC, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_TextIndent, (FX_LPCWSTR)L"text-indent", 0x169ADB74, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Right, (FX_LPCWSTR)L"right", 0x193ADE3E, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_TextEmphasisStyle, (FX_LPCWSTR)L"text-emphasis-style", 0x20DBAF4A, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_PaddingLeft, (FX_LPCWSTR)L"padding-left", 0x228CF02F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_ColumnWidth, (FX_LPCWSTR)L"column-width", 0x24C9AC9B, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_MarginLeft, (FX_LPCWSTR)L"margin-left", 0x297C5656, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Border, (FX_LPCWSTR)L"border", 0x2A23349E, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_BorderTop, (FX_LPCWSTR)L"border-top", 0x2B866ADE, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_RubyOverhang, (FX_LPCWSTR)L"ruby-overhang", 0x2CCA0D89, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_PageBreakBefore, (FX_LPCWSTR)L"page-break-before", 0x3119B36F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_MaxHeight, (FX_LPCWSTR)L"max-height", 0x343597EC, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_MinWidth, (FX_LPCWSTR)L"min-width", 0x35832871, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderLeftColor, (FX_LPCWSTR)L"border-left-color", 0x35C64022, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_Bottom, (FX_LPCWSTR)L"bottom", 0x399F02B5, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Quotes, (FX_LPCWSTR)L"quotes", 0x3D8C6A01, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_MaxWidth, (FX_LPCWSTR)L"max-width", 0x3EA274F3, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_PaddingRight, (FX_LPCWSTR)L"padding-right", 0x3F616AC2, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_ListStyleImage, (FX_LPCWSTR)L"list-style-image", 0x42A8A86A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeURI},
+ {FDE_CSSPROPERTY_WhiteSpace, (FX_LPCWSTR)L"white-space", 0x42F0429A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderBottom, (FX_LPCWSTR)L"border-bottom", 0x452CE780, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_ListStyleType, (FX_LPCWSTR)L"list-style-type", 0x48094789, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_WordBreak, (FX_LPCWSTR)L"word-break", 0x4D74A3CE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_OverflowX, (FX_LPCWSTR)L"overflow-x", 0x4ECEBF99, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_OverflowY, (FX_LPCWSTR)L"overflow-y", 0x4ECEBF9A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderTopColor, (FX_LPCWSTR)L"border-top-color", 0x5109B8CA, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_FontFamily, (FX_LPCWSTR)L"font-family", 0x574686E6, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_Cursor, (FX_LPCWSTR)L"cursor", 0x59DFCA5E, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_RubyAlign, (FX_LPCWSTR)L"ruby-align", 0x6077BDFA, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ColumnRuleColor, (FX_LPCWSTR)L"column-rule-color", 0x65DDFD9F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_FontWeight, (FX_LPCWSTR)L"font-weight", 0x6692F60C, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderRightStyle, (FX_LPCWSTR)L"border-right-style", 0x6920DDA7, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_MinHeight, (FX_LPCWSTR)L"min-height", 0x6AAE312A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Color, (FX_LPCWSTR)L"color", 0x6E67921F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_LetterSpacing, (FX_LPCWSTR)L"letter-spacing", 0x70536102, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_EmptyCells, (FX_LPCWSTR)L"empty-cells", 0x7531528F, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_TextAlign, (FX_LPCWSTR)L"text-align", 0x7553F1BD, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_RubySpan, (FX_LPCWSTR)L"ruby-span", 0x76FCFCE1, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeFunction},
+ {FDE_CSSPROPERTY_Position, (FX_LPCWSTR)L"position", 0x814F82B5, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderStyle, (FX_LPCWSTR)L"border-style", 0x82A4CD5C, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderBottomStyle, (FX_LPCWSTR)L"border-bottom-style", 0x88079DBE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderCollapse, (FX_LPCWSTR)L"border-collapse", 0x8883C7FE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ColumnCount, (FX_LPCWSTR)L"column-count", 0x89936A64, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderRightWidth, (FX_LPCWSTR)L"border-right-width", 0x8F5A6036, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_UnicodeBidi, (FX_LPCWSTR)L"unicode-bidi", 0x91670F6C, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_VerticalAlign, (FX_LPCWSTR)L"vertical-align", 0x934A87D2, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_PaddingTop, (FX_LPCWSTR)L"padding-top", 0x959D22B7, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Columns, (FX_LPCWSTR)L"columns", 0x96FA5D81, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_Overflow, (FX_LPCWSTR)L"overflow", 0x97B76B54, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_TableLayout, (FX_LPCWSTR)L"table-layout", 0x9B1CB4B3, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_FontVariant, (FX_LPCWSTR)L"font-variant", 0x9C785779, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ListStyle, (FX_LPCWSTR)L"list-style", 0x9E6C471A, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_BackgroundPosition, (FX_LPCWSTR)L"background-position", 0xA8846D22, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderWidth, (FX_LPCWSTR)L"border-width", 0xA8DE4FEB, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_TextEmphasisColor, (FX_LPCWSTR)L"text-emphasis-color", 0xAAF23478, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_BorderLeftStyle, (FX_LPCWSTR)L"border-left-style", 0xABAFBAF4, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_PageBreakInside, (FX_LPCWSTR)L"page-break-inside", 0xACB695F8, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_TextEmphasis, (FX_LPCWSTR)L"text-emphasis", 0xAD0E580C, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_BorderBottomWidth, (FX_LPCWSTR)L"border-bottom-width", 0xAE41204D, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_ColumnGap, (FX_LPCWSTR)L"column-gap", 0xB5C1BA73, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Orphans, (FX_LPCWSTR)L"orphans", 0xB716467B, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderRight, (FX_LPCWSTR)L"border-right", 0xB78E9EA9, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_FontSize, (FX_LPCWSTR)L"font-size", 0xB93956DF, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_PageBreakAfter, (FX_LPCWSTR)L"page-break-after", 0xBC358AEE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_CaptionSide, (FX_LPCWSTR)L"caption-side", 0xC03F3560, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BackgroundRepeat, (FX_LPCWSTR)L"background-repeat", 0xC2C2FDCE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderTopStyle, (FX_LPCWSTR)L"border-top-style", 0xC6F3339C, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderSpacing, (FX_LPCWSTR)L"border-spacing", 0xC72030F0, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_TextTransform, (FX_LPCWSTR)L"text-transform", 0xC88EEA6E, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_FontStyle, (FX_LPCWSTR)L"font-style", 0xCB1950F5, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Font, (FX_LPCWSTR)L"font", 0xCD308B77, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_LineHeight, (FX_LPCWSTR)L"line-height", 0xCFCACE2E, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_MarginRight, (FX_LPCWSTR)L"margin-right", 0xD13C58C9, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Float, (FX_LPCWSTR)L"float", 0xD1532876, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BorderLeftWidth, (FX_LPCWSTR)L"border-left-width", 0xD1E93D83, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_Display, (FX_LPCWSTR)L"display", 0xD4224C36, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Clear, (FX_LPCWSTR)L"clear", 0xD8ED1467, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_ColumnRuleStyle, (FX_LPCWSTR)L"column-rule-style", 0xDBC77871, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_TextCombine, (FX_LPCWSTR)L"text-combine", 0xDC5207CF, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_ListStylePosition, (FX_LPCWSTR)L"list-style-position", 0xE1A1DE3C, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Visibility, (FX_LPCWSTR)L"visibility", 0xE29F5168, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_PaddingBottom, (FX_LPCWSTR)L"padding-bottom", 0xE555B3B9, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BackgroundAttachment, (FX_LPCWSTR)L"background-attachment", 0xE77981F6, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_BackgroundImage, (FX_LPCWSTR)L"background-image", 0xE9AEB710, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeURI},
+ {FDE_CSSPROPERTY_LineBreak, (FX_LPCWSTR)L"line-break", 0xEA2D1D9A, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Background, (FX_LPCWSTR)L"background", 0xEB49DD40, FDE_CSSVALUETYPE_Shorthand},
+ {FDE_CSSPROPERTY_BorderTopWidth, (FX_LPCWSTR)L"border-top-width", 0xED2CB62B, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_WordSpacing, (FX_LPCWSTR)L"word-spacing", 0xEDA63BAE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_BorderRightColor, (FX_LPCWSTR)L"border-right-color", 0xF33762D5, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeColor},
+ {FDE_CSSPROPERTY_CounterIncrement, (FX_LPCWSTR)L"counter-increment", 0xF4CFB1B2, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeString},
+ {FDE_CSSPROPERTY_Left, (FX_LPCWSTR)L"left", 0xF5AD782B, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_TextDecoration, (FX_LPCWSTR)L"text-decoration", 0xF7C634BA, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Padding, (FX_LPCWSTR)L"padding", 0xF8C373F7, FDE_CSSVALUETYPE_List | FDE_CSSVALUETYPE_MaybeNumber},
+ {FDE_CSSPROPERTY_MarginBottom, (FX_LPCWSTR)L"margin-bottom", 0xF93485A0, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_MarginTop, (FX_LPCWSTR)L"margin-top", 0xFE51DCFE, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeNumber | FDE_CSSVALUETYPE_MaybeEnum},
+ {FDE_CSSPROPERTY_Direction, (FX_LPCWSTR)L"direction", 0xFE746E61, FDE_CSSVALUETYPE_Primitive | FDE_CSSVALUETYPE_MaybeEnum},
+ };
+ static const FDE_CSSPROPERTYVALUETABLE g_FDE_CSSPropertyValues[] = {
+ {FDE_CSSPROPERTYVALUE_Bolder, (FX_LPCWSTR)L"bolder", 0x009F1058},
+ {FDE_CSSPROPERTYVALUE_LowerLatin, (FX_LPCWSTR)L"lower-latin", 0x016014CE},
+ {FDE_CSSPROPERTYVALUE_Lowercase, (FX_LPCWSTR)L"lowercase", 0x02ACB805},
+ {FDE_CSSPROPERTYVALUE_LowerGreek, (FX_LPCWSTR)L"lower-greek", 0x03D81D64},
+ {FDE_CSSPROPERTYVALUE_Sesame, (FX_LPCWSTR)L"sesame", 0x0432ECDE},
+ {FDE_CSSPROPERTYVALUE_None, (FX_LPCWSTR)L"none", 0x048B6670},
+ {FDE_CSSPROPERTYVALUE_NwResize, (FX_LPCWSTR)L"nw-resize", 0x054B4BE4},
+ {FDE_CSSPROPERTYVALUE_WResize, (FX_LPCWSTR)L"w-resize", 0x0A2F8D76},
+ {FDE_CSSPROPERTYVALUE_Dot, (FX_LPCWSTR)L"dot", 0x0A48CB27},
+ {FDE_CSSPROPERTYVALUE_End, (FX_LPCWSTR)L"end", 0x0A631437},
+ {FDE_CSSPROPERTYVALUE_Ltr, (FX_LPCWSTR)L"ltr", 0x0B1B56D2},
+ {FDE_CSSPROPERTYVALUE_Pre, (FX_LPCWSTR)L"pre", 0x0B848587},
+ {FDE_CSSPROPERTYVALUE_Rtl, (FX_LPCWSTR)L"rtl", 0x0BB92C52},
+ {FDE_CSSPROPERTYVALUE_Sub, (FX_LPCWSTR)L"sub", 0x0BD37FAA},
+ {FDE_CSSPROPERTYVALUE_Top, (FX_LPCWSTR)L"top", 0x0BEDAF33},
+ {FDE_CSSPROPERTYVALUE_Visible, (FX_LPCWSTR)L"visible", 0x0F55D7EE},
+ {FDE_CSSPROPERTYVALUE_Filled, (FX_LPCWSTR)L"filled", 0x10827DD0},
+ {FDE_CSSPROPERTYVALUE_SwResize, (FX_LPCWSTR)L"sw-resize", 0x10B548E9},
+ {FDE_CSSPROPERTYVALUE_NoRepeat, (FX_LPCWSTR)L"no-repeat", 0x1235C18B},
+ {FDE_CSSPROPERTYVALUE_Default, (FX_LPCWSTR)L"default", 0x14DA2125},
+ {FDE_CSSPROPERTYVALUE_Transparent, (FX_LPCWSTR)L"transparent", 0x17B64DB2},
+ {FDE_CSSPROPERTYVALUE_Ridge, (FX_LPCWSTR)L"ridge", 0x18EBEE4B},
+ {FDE_CSSPROPERTYVALUE_Right, (FX_LPCWSTR)L"right", 0x193ADE3E},
+ {FDE_CSSPROPERTYVALUE_HorizontalTb, (FX_LPCWSTR)L"horizontal-tb", 0x1A66A86D},
+ {FDE_CSSPROPERTYVALUE_DistributeLetter, (FX_LPCWSTR)L"distribute-letter", 0x1EDBD75C},
+ {FDE_CSSPROPERTYVALUE_DoubleCircle, (FX_LPCWSTR)L"double-circle", 0x1FF082BA},
+ {FDE_CSSPROPERTYVALUE_Ruby, (FX_LPCWSTR)L"ruby", 0x20D66C02},
+ {FDE_CSSPROPERTYVALUE_Collapse, (FX_LPCWSTR)L"collapse", 0x2128D673},
+ {FDE_CSSPROPERTYVALUE_Normal, (FX_LPCWSTR)L"normal", 0x247CF3E9},
+ {FDE_CSSPROPERTYVALUE_Avoid, (FX_LPCWSTR)L"avoid", 0x24E684B3},
+ {FDE_CSSPROPERTYVALUE_UpperRoman, (FX_LPCWSTR)L"upper-roman", 0x28BAC2B6},
+ {FDE_CSSPROPERTYVALUE_Auto, (FX_LPCWSTR)L"auto", 0x2B35B6D9},
+ {FDE_CSSPROPERTYVALUE_Text, (FX_LPCWSTR)L"text", 0x2D08AF85},
+ {FDE_CSSPROPERTYVALUE_XSmall, (FX_LPCWSTR)L"x-small", 0x2D2FCAFE},
+ {FDE_CSSPROPERTYVALUE_Thin, (FX_LPCWSTR)L"thin", 0x2D574D53},
+ {FDE_CSSPROPERTYVALUE_Repeat, (FX_LPCWSTR)L"repeat", 0x306614A1},
+ {FDE_CSSPROPERTYVALUE_Small, (FX_LPCWSTR)L"small", 0x316A3739},
+ {FDE_CSSPROPERTYVALUE_NeResize, (FX_LPCWSTR)L"ne-resize", 0x31FD5E12},
+ {FDE_CSSPROPERTYVALUE_NoContent, (FX_LPCWSTR)L"no-content", 0x33A1C545},
+ {FDE_CSSPROPERTYVALUE_Outside, (FX_LPCWSTR)L"outside", 0x36DF693D},
+ {FDE_CSSPROPERTYVALUE_EResize, (FX_LPCWSTR)L"e-resize", 0x36E19FA4},
+ {FDE_CSSPROPERTYVALUE_TableRow, (FX_LPCWSTR)L"table-row", 0x3912A02D},
+ {FDE_CSSPROPERTYVALUE_Bottom, (FX_LPCWSTR)L"bottom", 0x399F02B5},
+ {FDE_CSSPROPERTYVALUE_Underline, (FX_LPCWSTR)L"underline", 0x3A0273A6},
+ {FDE_CSSPROPERTYVALUE_CjkIdeographic, (FX_LPCWSTR)L"cjk-ideographic", 0x3A641CC4},
+ {FDE_CSSPROPERTYVALUE_SeResize, (FX_LPCWSTR)L"se-resize", 0x3D675B17},
+ {FDE_CSSPROPERTYVALUE_Fixed, (FX_LPCWSTR)L"fixed", 0x3D7DEB10},
+ {FDE_CSSPROPERTYVALUE_Double, (FX_LPCWSTR)L"double", 0x3D98515B},
+ {FDE_CSSPROPERTYVALUE_Solid, (FX_LPCWSTR)L"solid", 0x40623B5B},
+ {FDE_CSSPROPERTYVALUE_RubyBaseGroup, (FX_LPCWSTR)L"ruby-base-group", 0x41014E84},
+ {FDE_CSSPROPERTYVALUE_OpenQuote, (FX_LPCWSTR)L"open-quote", 0x44A41E8D},
+ {FDE_CSSPROPERTYVALUE_Lighter, (FX_LPCWSTR)L"lighter", 0x45BEB7AF},
+ {FDE_CSSPROPERTYVALUE_LowerRoman, (FX_LPCWSTR)L"lower-roman", 0x5044D253},
+ {FDE_CSSPROPERTYVALUE_Strict, (FX_LPCWSTR)L"strict", 0x52F4EBD9},
+ {FDE_CSSPROPERTYVALUE_TableCaption, (FX_LPCWSTR)L"table-caption", 0x5325CD63},
+ {FDE_CSSPROPERTYVALUE_Oblique, (FX_LPCWSTR)L"oblique", 0x53EBDDB1},
+ {FDE_CSSPROPERTYVALUE_Decimal, (FX_LPCWSTR)L"decimal", 0x54034C2F},
+ {FDE_CSSPROPERTYVALUE_Loose, (FX_LPCWSTR)L"loose", 0x54D3A1E2},
+ {FDE_CSSPROPERTYVALUE_Hebrew, (FX_LPCWSTR)L"hebrew", 0x565792DD},
+ {FDE_CSSPROPERTYVALUE_Hidden, (FX_LPCWSTR)L"hidden", 0x573CB40C},
+ {FDE_CSSPROPERTYVALUE_Dashed, (FX_LPCWSTR)L"dashed", 0x58A3DD29},
+ {FDE_CSSPROPERTYVALUE_Embed, (FX_LPCWSTR)L"embed", 0x59C8F27D},
+ {FDE_CSSPROPERTYVALUE_TableRowGroup, (FX_LPCWSTR)L"table-row-group", 0x5A43BD07},
+ {FDE_CSSPROPERTYVALUE_TableColumn, (FX_LPCWSTR)L"table-column", 0x5E705DA3},
+ {FDE_CSSPROPERTYVALUE_Static, (FX_LPCWSTR)L"static", 0x5E7555E8},
+ {FDE_CSSPROPERTYVALUE_Outset, (FX_LPCWSTR)L"outset", 0x61236164},
+ {FDE_CSSPROPERTYVALUE_DecimalLeadingZero, (FX_LPCWSTR)L"decimal-leading-zero", 0x61DFC55D},
+ {FDE_CSSPROPERTYVALUE_KeepWords, (FX_LPCWSTR)L"keep-words", 0x63964801},
+ {FDE_CSSPROPERTYVALUE_KatakanaIroha, (FX_LPCWSTR)L"katakana-iroha", 0x65D7C91C},
+ {FDE_CSSPROPERTYVALUE_Super, (FX_LPCWSTR)L"super", 0x6A4F842F},
+ {FDE_CSSPROPERTYVALUE_Center, (FX_LPCWSTR)L"center", 0x6C51AFC1},
+ {FDE_CSSPROPERTYVALUE_TableHeaderGroup, (FX_LPCWSTR)L"table-header-group", 0x706103D8},
+ {FDE_CSSPROPERTYVALUE_Inside, (FX_LPCWSTR)L"inside", 0x709CB0FC},
+ {FDE_CSSPROPERTYVALUE_XxLarge, (FX_LPCWSTR)L"xx-large", 0x70BB1508},
+ {FDE_CSSPROPERTYVALUE_Triangle, (FX_LPCWSTR)L"triangle", 0x7524EDF6},
+ {FDE_CSSPROPERTYVALUE_RubyTextGroup, (FX_LPCWSTR)L"ruby-text-group", 0x78C2B98E},
+ {FDE_CSSPROPERTYVALUE_Circle, (FX_LPCWSTR)L"circle", 0x7ABEC0D2},
+ {FDE_CSSPROPERTYVALUE_Hiragana, (FX_LPCWSTR)L"hiragana", 0x7BF5E25B},
+ {FDE_CSSPROPERTYVALUE_RepeatX, (FX_LPCWSTR)L"repeat-x", 0x7C8F3226},
+ {FDE_CSSPROPERTYVALUE_RepeatY, (FX_LPCWSTR)L"repeat-y", 0x7C8F3227},
+ {FDE_CSSPROPERTYVALUE_Move, (FX_LPCWSTR)L"move", 0x7DA03417},
+ {FDE_CSSPROPERTYVALUE_HiraganaIroha, (FX_LPCWSTR)L"hiragana-iroha", 0x7EE863FB},
+ {FDE_CSSPROPERTYVALUE_RubyBase, (FX_LPCWSTR)L"ruby-base", 0x7FD1B1EA},
+ {FDE_CSSPROPERTYVALUE_Scroll, (FX_LPCWSTR)L"scroll", 0x84787AEF},
+ {FDE_CSSPROPERTYVALUE_Smaller, (FX_LPCWSTR)L"smaller", 0x849769F0},
+ {FDE_CSSPROPERTYVALUE_TableFooterGroup, (FX_LPCWSTR)L"table-footer-group", 0x85BDD97E},
+ {FDE_CSSPROPERTYVALUE_Baseline, (FX_LPCWSTR)L"baseline", 0x87436BA3},
+ {FDE_CSSPROPERTYVALUE_Separate, (FX_LPCWSTR)L"separate", 0x877C66B5},
+ {FDE_CSSPROPERTYVALUE_Armenian, (FX_LPCWSTR)L"armenian", 0x889BE4EB},
+ {FDE_CSSPROPERTYVALUE_Open, (FX_LPCWSTR)L"open", 0x8B90E1F2},
+ {FDE_CSSPROPERTYVALUE_Relative, (FX_LPCWSTR)L"relative", 0x8C995B5C},
+ {FDE_CSSPROPERTYVALUE_Thick, (FX_LPCWSTR)L"thick", 0x8CC35EB3},
+ {FDE_CSSPROPERTYVALUE_Justify, (FX_LPCWSTR)L"justify", 0x8D269CAE},
+ {FDE_CSSPROPERTYVALUE_Middle, (FX_LPCWSTR)L"middle", 0x947FA00F},
+ {FDE_CSSPROPERTYVALUE_Always, (FX_LPCWSTR)L"always", 0x959AB231},
+ {FDE_CSSPROPERTYVALUE_DistributeSpace, (FX_LPCWSTR)L"distribute-space", 0x97A20E58},
+ {FDE_CSSPROPERTYVALUE_LineEdge, (FX_LPCWSTR)L"line-edge", 0x9A845D2A},
+ {FDE_CSSPROPERTYVALUE_PreWrap, (FX_LPCWSTR)L"pre-wrap", 0x9D59588E},
+ {FDE_CSSPROPERTYVALUE_Medium, (FX_LPCWSTR)L"medium", 0xA084A381},
+ {FDE_CSSPROPERTYVALUE_NResize, (FX_LPCWSTR)L"n-resize", 0xA088968D},
+ {FDE_CSSPROPERTYVALUE_ListItem, (FX_LPCWSTR)L"list-item", 0xA32382B8},
+ {FDE_CSSPROPERTYVALUE_Show, (FX_LPCWSTR)L"show", 0xA66C10C1},
+ {FDE_CSSPROPERTYVALUE_Currentcolor, (FX_LPCWSTR)L"currentColor", 0xA7883922},
+ {FDE_CSSPROPERTYVALUE_NoCloseQuote, (FX_LPCWSTR)L"no-close-quote", 0xA79CBFFB},
+ {FDE_CSSPROPERTYVALUE_VerticalLr, (FX_LPCWSTR)L"vertical-lr", 0xA8673F65},
+ {FDE_CSSPROPERTYVALUE_VerticalRl, (FX_LPCWSTR)L"vertical-rl", 0xA8675E25},
+ {FDE_CSSPROPERTYVALUE_Pointer, (FX_LPCWSTR)L"pointer", 0xA90929C1},
+ {FDE_CSSPROPERTYVALUE_XxSmall, (FX_LPCWSTR)L"xx-small", 0xADE1FC76},
+ {FDE_CSSPROPERTYVALUE_Bold, (FX_LPCWSTR)L"bold", 0xB18313A1},
+ {FDE_CSSPROPERTYVALUE_Both, (FX_LPCWSTR)L"both", 0xB1833CAD},
+ {FDE_CSSPROPERTYVALUE_SmallCaps, (FX_LPCWSTR)L"small-caps", 0xB299428D},
+ {FDE_CSSPROPERTYVALUE_Katakana, (FX_LPCWSTR)L"katakana", 0xB421A4BC},
+ {FDE_CSSPROPERTYVALUE_After, (FX_LPCWSTR)L"after", 0xB6B44172},
+ {FDE_CSSPROPERTYVALUE_Horizontal, (FX_LPCWSTR)L"horizontal", 0xB7732DEA},
+ {FDE_CSSPROPERTYVALUE_Dotted, (FX_LPCWSTR)L"dotted", 0xB88652A4},
+ {FDE_CSSPROPERTYVALUE_Disc, (FX_LPCWSTR)L"disc", 0xBEBC18C3},
+ {FDE_CSSPROPERTYVALUE_Georgian, (FX_LPCWSTR)L"georgian", 0xBEF99E8C},
+ {FDE_CSSPROPERTYVALUE_Inline, (FX_LPCWSTR)L"inline", 0xC02D649F},
+ {FDE_CSSPROPERTYVALUE_Overline, (FX_LPCWSTR)L"overline", 0xC0EC9FA4},
+ {FDE_CSSPROPERTYVALUE_Wait, (FX_LPCWSTR)L"wait", 0xC1613BB5},
+ {FDE_CSSPROPERTYVALUE_BreakAll, (FX_LPCWSTR)L"break-all", 0xC3145BAB},
+ {FDE_CSSPROPERTYVALUE_UpperAlpha, (FX_LPCWSTR)L"upper-alpha", 0xC52D4A9F},
+ {FDE_CSSPROPERTYVALUE_Capitalize, (FX_LPCWSTR)L"capitalize", 0xC5321D46},
+ {FDE_CSSPROPERTYVALUE_Nowrap, (FX_LPCWSTR)L"nowrap", 0xC7994417},
+ {FDE_CSSPROPERTYVALUE_TextBottom, (FX_LPCWSTR)L"text-bottom", 0xC7D08D87},
+ {FDE_CSSPROPERTYVALUE_NoOpenQuote, (FX_LPCWSTR)L"no-open-quote", 0xC8CD7877},
+ {FDE_CSSPROPERTYVALUE_Groove, (FX_LPCWSTR)L"groove", 0xCB24A412},
+ {FDE_CSSPROPERTYVALUE_Progress, (FX_LPCWSTR)L"progress", 0xCD1D9835},
+ {FDE_CSSPROPERTYVALUE_Larger, (FX_LPCWSTR)L"larger", 0xCD3C409D},
+ {FDE_CSSPROPERTYVALUE_CloseQuote, (FX_LPCWSTR)L"close-quote", 0xCF8696D1},
+ {FDE_CSSPROPERTYVALUE_TableCell, (FX_LPCWSTR)L"table-cell", 0xCFB5E595},
+ {FDE_CSSPROPERTYVALUE_PreLine, (FX_LPCWSTR)L"pre-line", 0xD04FEDBC},
+ {FDE_CSSPROPERTYVALUE_Absolute, (FX_LPCWSTR)L"absolute", 0xD0B2D55F},
+ {FDE_CSSPROPERTYVALUE_InlineTable, (FX_LPCWSTR)L"inline-table", 0xD131F494},
+ {FDE_CSSPROPERTYVALUE_BidiOverride, (FX_LPCWSTR)L"bidi-override", 0xD161FDE5},
+ {FDE_CSSPROPERTYVALUE_InlineBlock, (FX_LPCWSTR)L"inline-block", 0xD26A8BD7},
+ {FDE_CSSPROPERTYVALUE_Inset, (FX_LPCWSTR)L"inset", 0xD6F23243},
+ {FDE_CSSPROPERTYVALUE_Crosshair, (FX_LPCWSTR)L"crosshair", 0xD6F8018E},
+ {FDE_CSSPROPERTYVALUE_UpperLatin, (FX_LPCWSTR)L"upper-latin", 0xD9D60531},
+ {FDE_CSSPROPERTYVALUE_Help, (FX_LPCWSTR)L"help", 0xDA002969},
+ {FDE_CSSPROPERTYVALUE_Hide, (FX_LPCWSTR)L"hide", 0xDA69395A},
+ {FDE_CSSPROPERTYVALUE_Uppercase, (FX_LPCWSTR)L"uppercase", 0xDAD595A8},
+ {FDE_CSSPROPERTYVALUE_SResize, (FX_LPCWSTR)L"s-resize", 0xDB3AADF2},
+ {FDE_CSSPROPERTYVALUE_Table, (FX_LPCWSTR)L"table", 0xDB9BE968},
+ {FDE_CSSPROPERTYVALUE_Blink, (FX_LPCWSTR)L"blink", 0xDC36E390},
+ {FDE_CSSPROPERTYVALUE_Block, (FX_LPCWSTR)L"block", 0xDCD480AB},
+ {FDE_CSSPROPERTYVALUE_Start, (FX_LPCWSTR)L"start", 0xE1D9D5AE},
+ {FDE_CSSPROPERTYVALUE_TableColumnGroup, (FX_LPCWSTR)L"table-column-group", 0xE2258EFD},
+ {FDE_CSSPROPERTYVALUE_Italic, (FX_LPCWSTR)L"italic", 0xE31D5396},
+ {FDE_CSSPROPERTYVALUE_LineThrough, (FX_LPCWSTR)L"line-through", 0xE4C5A276},
+ {FDE_CSSPROPERTYVALUE_KeepAll, (FX_LPCWSTR)L"keep-all", 0xE704A72B},
+ {FDE_CSSPROPERTYVALUE_LowerAlpha, (FX_LPCWSTR)L"lower-alpha", 0xECB75A3C},
+ {FDE_CSSPROPERTYVALUE_RunIn, (FX_LPCWSTR)L"run-in", 0xEEC930B9},
+ {FDE_CSSPROPERTYVALUE_Square, (FX_LPCWSTR)L"square", 0xEF85D351},
+ {FDE_CSSPROPERTYVALUE_XLarge, (FX_LPCWSTR)L"x-large", 0xF008E390},
+ {FDE_CSSPROPERTYVALUE_Large, (FX_LPCWSTR)L"large", 0xF4434FCB},
+ {FDE_CSSPROPERTYVALUE_Before, (FX_LPCWSTR)L"before", 0xF4FFCE73},
+ {FDE_CSSPROPERTYVALUE_Left, (FX_LPCWSTR)L"left", 0xF5AD782B},
+ {FDE_CSSPROPERTYVALUE_TextTop, (FX_LPCWSTR)L"text-top", 0xFCB58D45},
+ {FDE_CSSPROPERTYVALUE_RubyText, (FX_LPCWSTR)L"ruby-text", 0xFCC77174},
+ {FDE_CSSPROPERTYVALUE_NoDisplay, (FX_LPCWSTR)L"no-display", 0xFE482860},
+ };
+ static const FDE_CSSMEDIATYPETABLE g_FDE_CSSMediaTypes[] = {
+ {0xF09, 0x02},
+ {0x4880, 0x20},
+ {0x536A, 0x80},
+ {0x741D, 0x10},
+ {0x76ED, 0x08},
+ {0x7CFB, 0x01},
+ {0x9578, 0x04},
+ {0xC8E1, 0x40},
+ {0xD0F9, 0xFF},
+ };
+ static const FDE_CSSLENGTHUNITTABLE g_FDE_CSSLengthUnits[] = {
+ {0x0672, 3},
+ {0x067D, 4},
+ {0x1AF7, 8},
+ {0x2F7A, 7},
+ {0x3ED3, 10},
+ {0x3EE4, 9},
+ {0x3EE8, 5},
+ {0xFC30, 6},
+ };
+ static const FDE_CSSCOLORTABLE g_FDE_CSSColors[] = {
+ {0x031B47FE, 0xff000080},
+ {0x0BB8DF5B, 0xffff0000},
+ {0x0D82A78C, 0xff800000},
+ {0x2ACC82E8, 0xff00ffff},
+ {0x2D083986, 0xff008080},
+ {0x4A6A6195, 0xffc0c0c0},
+ {0x546A8EF3, 0xff808080},
+ {0x65C9169C, 0xffffa500},
+ {0x8422BB61, 0xffffffff},
+ {0x9271A558, 0xff800080},
+ {0xA65A3EE3, 0xffff00ff},
+ {0xB1345708, 0xff0000ff},
+ {0xB6D2CF1F, 0xff808000},
+ {0xD19B5E1C, 0xffffff00},
+ {0xDB64391D, 0xff000000},
+ {0xF616D507, 0xff00ff00},
+ {0xF6EFFF31, 0xff008000},
+ };
+ static const FDE_CSSPERSUDOTABLE g_FDE_CSSPersudoType[] = {
+ {FDE_CSSPERSUDO_After, (FX_LPCWSTR)L":after", 0x16EE1FEC},
+ {FDE_CSSPERSUDO_Before, (FX_LPCWSTR)L":before", 0x7DCDDE2D},
+ };
+ FDE_LPCCSSPERSUDOTABLE FDE_GetCSSPersudoByEnum(FDE_CSSPERSUDO ePersudo)
+ {
+ return (ePersudo < FDE_CSSPERSUDO_NONE) ? (g_FDE_CSSPersudoType + ePersudo) : NULL;
+ }
+ FDE_LPCCSSPROPERTYTABLE FDE_GetCSSPropertyByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_DWORD dwHash = FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = FDE_CSSPROPERTY_MAX - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_DWORD dwMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ dwMid = g_FDE_CSSProperties[iMid].dwHash;
+ if (dwHash == dwMid) {
+ return g_FDE_CSSProperties + iMid;
+ } else if (dwHash > dwMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FDE_LPCCSSPROPERTYTABLE FDE_GetCSSPropertyByEnum(FDE_CSSPROPERTY eName)
+ {
+ return (eName < FDE_CSSPROPERTY_MAX) ? (g_FDE_CSSProperties + eName) : NULL;
+ }
+ FDE_LPCCSSPROPERTYVALUETABLE FDE_GetCSSPropertyValueByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_DWORD dwHash = FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = FDE_CSSPROPERTYVALUE_MAX - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_DWORD dwMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ dwMid = g_FDE_CSSPropertyValues[iMid].dwHash;
+ if (dwHash == dwMid) {
+ return g_FDE_CSSPropertyValues + iMid;
+ } else if (dwHash > dwMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FDE_LPCCSSPROPERTYVALUETABLE FDE_GetCSSPropertyValueByEnum(FDE_CSSPROPERTYVALUE eName)
+ {
+ return (eName < FDE_CSSPROPERTYVALUE_MAX) ? (g_FDE_CSSPropertyValues + eName) : NULL;
+ }
+ FDE_LPCCSSMEDIATYPETABLE FDE_GetCSSMediaTypeByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_WORD wHash = (FX_WORD)FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = sizeof(g_FDE_CSSMediaTypes) / sizeof(FDE_CSSMEDIATYPETABLE) - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_WORD uMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ uMid = g_FDE_CSSMediaTypes[iMid].wHash;
+ if (wHash == uMid) {
+ return g_FDE_CSSMediaTypes + iMid;
+ } else if (wHash > uMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FDE_LPCCSSLENGTHUNITTABLE FDE_GetCSSLengthUnitByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_WORD wHash = (FX_WORD)FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = sizeof(g_FDE_CSSLengthUnits) / sizeof(FDE_CSSLENGTHUNITTABLE) - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_WORD wMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ wMid = g_FDE_CSSLengthUnits[iMid].wHash;
+ if (wHash == wMid) {
+ return g_FDE_CSSLengthUnits + iMid;
+ } else if (wHash > wMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FDE_LPCCSSCOLORTABLE FDE_GetCSSColorByName(FX_LPCWSTR pszName, FX_INT32 iLength)
+ {
+ FXSYS_assert(pszName != NULL && iLength > 0);
+ FX_DWORD dwHash = FX_HashCode_String_GetW(pszName, iLength, TRUE);
+ FX_INT32 iEnd = sizeof(g_FDE_CSSColors) / sizeof(FDE_CSSCOLORTABLE) - 1;
+ FX_INT32 iMid, iStart = 0;
+ FX_DWORD dwMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ dwMid = g_FDE_CSSColors[iMid].dwHash;
+ if (dwHash == dwMid) {
+ return g_FDE_CSSColors + iMid;
+ } else if (dwHash > dwMid) {
+ iStart = iMid + 1;
+ } else {
+ iEnd = iMid - 1;
+ }
+ } while (iStart <= iEnd);
+ return NULL;
+ }
+ FX_BOOL FDE_ParseCSSNumber(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_FLOAT &fValue, FDE_CSSPRIMITIVETYPE &eUnit)
+ {
+ FXSYS_assert(pszValue != NULL && iValueLen > 0);
+ FX_INT32 iUsedLen = 0;
+ fValue = FX_wcstof(pszValue, iValueLen, &iUsedLen);
+ if (iUsedLen <= 0) {
+ return FALSE;
+ }
+ iValueLen -= iUsedLen;
+ pszValue += iUsedLen;
+ eUnit = FDE_CSSPRIMITIVETYPE_Number;
+ if (iValueLen >= 1 && *pszValue == '%') {
+ eUnit = FDE_CSSPRIMITIVETYPE_Percent;
+ } else if (iValueLen == 2) {
+ FDE_LPCCSSLENGTHUNITTABLE pUnit = FDE_GetCSSLengthUnitByName(pszValue, 2);
+ if (pUnit != NULL) {
+ eUnit = (FDE_CSSPRIMITIVETYPE)pUnit->wValue;
+ }
+ }
+ return TRUE;
+ }
+
+ FX_BOOL FDE_ParseCSSString(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_INT32 &iOffset, FX_INT32 &iLength)
+ {
+ FXSYS_assert(pszValue != NULL && iValueLen > 0);
+ iOffset = 0;
+ iLength = iValueLen;
+ if (iValueLen >= 2) {
+ FX_WCHAR first = pszValue[0], last = pszValue[iValueLen - 1];
+ if ((first == '\"' && last == '\"') || (first == '\'' && last == '\'')) {
+ iOffset = 1, iLength -= 2;
+ }
+ }
+ return iValueLen > 0;
+ }
+
+ FX_BOOL FDE_ParseCSSURI(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_INT32 &iOffset, FX_INT32 &iLength)
+ {
+ FXSYS_assert(pszValue != NULL && iValueLen > 0);
+ if (iValueLen < 6 || pszValue[iValueLen - 1] != ')' || FX_wcsnicmp((FX_LPCWSTR)L"url(", pszValue, 4)) {
+ return FALSE;
+ }
+ if (FDE_ParseCSSString(pszValue + 4, iValueLen - 5, iOffset, iLength)) {
+ iOffset += 4;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ FX_BOOL FDE_ParseCSSColor(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_ARGB &dwColor)
+ {
+ FXSYS_assert(pszValue != NULL && iValueLen > 0);
+ if (*pszValue == '#') {
+ switch (iValueLen) {
+ case 4: {
+ FX_BYTE red = FX_Hex2Dec((FX_BYTE)pszValue[1], (FX_BYTE)pszValue[1]);
+ FX_BYTE green = FX_Hex2Dec((FX_BYTE)pszValue[2], (FX_BYTE)pszValue[2]);
+ FX_BYTE blue = FX_Hex2Dec((FX_BYTE)pszValue[3], (FX_BYTE)pszValue[3]);
+ dwColor = ArgbEncode(255, red, green, blue);
+ }
+ return TRUE;
+ case 7: {
+ FX_BYTE red = FX_Hex2Dec((FX_BYTE)pszValue[1], (FX_BYTE)pszValue[2]);
+ FX_BYTE green = FX_Hex2Dec((FX_BYTE)pszValue[3], (FX_BYTE)pszValue[4]);
+ FX_BYTE blue = FX_Hex2Dec((FX_BYTE)pszValue[5], (FX_BYTE)pszValue[6]);
+ dwColor = ArgbEncode(255, red, green, blue);
+ }
+ return TRUE;
+ }
+ } else if (iValueLen >= 10) {
+ if (pszValue[iValueLen - 1] != ')' || FX_wcsnicmp((FX_LPCWSTR)L"rgb(", pszValue, 4)) {
+ return FALSE;
+ }
+ FX_BYTE rgb[3] = {0};
+ FX_FLOAT fValue;
+ FDE_CSSPRIMITIVETYPE eType;
+ CFDE_CSSValueListParser list(pszValue + 4, iValueLen - 5, ',');
+ for (FX_INT32 i = 0; i < 3; ++i) {
+ if (!list.NextValue(eType, pszValue, iValueLen)) {
+ return FALSE;
+ }
+ if (eType != FDE_CSSPRIMITIVETYPE_Number) {
+ return FALSE;
+ }
+ if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ return FALSE;
+ }
+ rgb[i] = eType == FDE_CSSPRIMITIVETYPE_Percent ? FXSYS_round(fValue * 2.55f) : FXSYS_round(fValue);
+ }
+ dwColor = ArgbEncode(255, rgb[0], rgb[1], rgb[2]);
+ return TRUE;
+ } else {
+ FDE_LPCCSSCOLORTABLE pColor = FDE_GetCSSColorByName(pszValue, iValueLen);
+ if (pColor != NULL) {
+ dwColor = pColor->dwValue;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+#ifdef _cplusplus
+};
+#endif
+CFDE_CSSValueList::CFDE_CSSValueList(IFX_MEMAllocator *pStaticStore, const CFDE_CSSValueArray &list)
+{
+ m_iCount = list.GetSize();
+ FX_INT32 iByteCount = m_iCount * sizeof(IFDE_CSSValue*);
+ m_ppList = (IFDE_CSSValue**)pStaticStore->Alloc(iByteCount);
+ FXSYS_memcpy(m_ppList, list.GetData(), iByteCount);
+}
+FX_BOOL CFDE_CSSValueListParser::NextValue(FDE_CSSPRIMITIVETYPE &eType, FX_LPCWSTR &pStart, FX_INT32 &iLength)
+{
+ while (m_pCur < m_pEnd && (*m_pCur <= ' ' || *m_pCur == m_Separator)) {
+ ++m_pCur;
+ }
+ if (m_pCur >= m_pEnd) {
+ return FALSE;
+ }
+ eType = FDE_CSSPRIMITIVETYPE_Unknown;
+ pStart = m_pCur;
+ iLength = 0;
+ FX_WCHAR wch = *m_pCur;
+ if (wch == '#') {
+ iLength = SkipTo(' ');
+ if (iLength == 4 || iLength == 7) {
+ eType = FDE_CSSPRIMITIVETYPE_RGB;
+ }
+ } else if ((wch >= '0' && wch <= '9') || wch == '.' || wch == '-' || wch == '+') {
+ while (m_pCur < m_pEnd && (*m_pCur > ' ' && *m_pCur != m_Separator)) {
+ ++m_pCur;
+ }
+ iLength = m_pCur - pStart;
+ if (iLength > 0) {
+ eType = FDE_CSSPRIMITIVETYPE_Number;
+ }
+ } else if (wch == '\"' || wch == '\'') {
+ pStart++;
+ iLength = SkipTo(wch) - 1;
+ m_pCur++;
+ eType = FDE_CSSPRIMITIVETYPE_String;
+ } else if (m_pEnd - m_pCur > 5 && m_pCur[3] == '(') {
+ if (FX_wcsnicmp((FX_LPCWSTR)L"url", m_pCur, 3) == 0) {
+ wch = m_pCur[4];
+ if (wch == '\"' || wch == '\'') {
+ pStart += 5;
+ iLength = SkipTo(wch) - 6;
+ m_pCur += 2;
+ } else {
+ pStart += 4;
+ iLength = SkipTo(')') - 4;
+ m_pCur++;
+ }
+ eType = FDE_CSSPRIMITIVETYPE_URI;
+ } else if (FX_wcsnicmp((FX_LPCWSTR)L"rgb", m_pCur, 3) == 0) {
+ iLength = SkipTo(')') + 1;
+ m_pCur++;
+ eType = FDE_CSSPRIMITIVETYPE_RGB;
+ }
+ } else {
+ iLength = SkipTo(m_Separator, TRUE, TRUE);
+ eType = FDE_CSSPRIMITIVETYPE_String;
+ }
+ return m_pCur <= m_pEnd && iLength > 0;
+}
+FX_INT32 CFDE_CSSValueListParser::SkipTo(FX_WCHAR wch, FX_BOOL bWSSeparator , FX_BOOL bBrContinue )
+{
+ FX_LPCWSTR pStart = m_pCur;
+ if (!bBrContinue) {
+ if (bWSSeparator)
+ while (++m_pCur < m_pEnd && *m_pCur != wch && *m_pCur > ' ') ;
+ else
+ while (++m_pCur < m_pEnd && *m_pCur != wch) ;
+ } else {
+ FX_INT32 iBracketCount = 0;
+ if (bWSSeparator) {
+ while (m_pCur < m_pEnd && *m_pCur != wch && *m_pCur > ' ') {
+ if (*m_pCur == '(') {
+ iBracketCount++;
+ } else if (*m_pCur == ')') {
+ iBracketCount--;
+ }
+ m_pCur++;
+ }
+ } else {
+ while (m_pCur < m_pEnd && *m_pCur != wch) {
+ if (*m_pCur == '(') {
+ iBracketCount++;
+ } else if (*m_pCur == ')') {
+ iBracketCount--;
+ }
+ m_pCur++;
+ }
+ }
+ while (iBracketCount > 0 && m_pCur < m_pEnd) {
+ if (*m_pCur == ')') {
+ iBracketCount--;
+ }
+ m_pCur++;
+ }
+ }
+ return m_pCur - pStart;
+}
diff --git a/xfa/src/fdp/src/css/fde_cssdatatable.h b/xfa/src/fdp/src/css/fde_cssdatatable.h
new file mode 100644
index 0000000000..0ebcccfab7
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssdatatable.h
@@ -0,0 +1,195 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSDATATABLE
+#define _FDE_CSSDATATABLE
+class CFDE_CSSFunction: public CFX_Target
+{
+public:
+ CFDE_CSSFunction(FX_LPCWSTR pszFuncName, IFDE_CSSValueList *pArgList): m_pszFuncName(pszFuncName), m_pArgList(pArgList)
+ {
+ FXSYS_assert(pArgList != NULL);
+ }
+ FX_INT32 CountArgs() const
+ {
+ return m_pArgList->CountValues();
+ }
+ IFDE_CSSValue* GetArgs(FX_INT32 index) const
+ {
+ return m_pArgList->GetValue(index);
+ }
+ FX_LPCWSTR GetFuncName() const
+ {
+ return m_pszFuncName;
+ };
+
+protected:
+ IFDE_CSSValueList *m_pArgList;
+ FX_LPCWSTR m_pszFuncName;
+};
+class CFDE_CSSPrimitiveValue : public IFDE_CSSPrimitiveValue, public CFX_Target
+{
+public:
+ CFDE_CSSPrimitiveValue(const CFDE_CSSPrimitiveValue &src)
+ {
+ *this = src;
+ }
+ CFDE_CSSPrimitiveValue(FX_ARGB color) : m_eType(FDE_CSSPRIMITIVETYPE_RGB), m_dwColor(color) { }
+ CFDE_CSSPrimitiveValue(FDE_CSSPROPERTYVALUE eValue) : m_eType(FDE_CSSPRIMITIVETYPE_Enum) , m_eEnum(eValue) { }
+ CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE eType, FX_FLOAT fValue) : m_eType(eType), m_fNumber(fValue) { }
+ CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE eType, FX_LPCWSTR pValue) : m_eType(eType), m_pString(pValue)
+ {
+ FXSYS_assert(m_pString != NULL);
+ }
+ CFDE_CSSPrimitiveValue(CFDE_CSSFunction *pFunction) : m_eType(FDE_CSSPRIMITIVETYPE_Function), m_pFunction(pFunction) {}
+
+ virtual FDE_CSSPRIMITIVETYPE GetPrimitiveType() const
+ {
+ return m_eType;
+ }
+
+ virtual FX_ARGB GetRGBColor() const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_RGB);
+ return m_dwColor;
+ }
+ virtual FX_FLOAT GetFloat() const
+ {
+ FXSYS_assert(m_eType >= FDE_CSSPRIMITIVETYPE_Number && m_eType <= FDE_CSSPRIMITIVETYPE_PC);
+ return m_fNumber;
+ }
+ virtual FX_LPCWSTR GetString(FX_INT32 &iLength) const
+ {
+ FXSYS_assert(m_eType >= FDE_CSSPRIMITIVETYPE_String && m_eType <= FDE_CSSPRIMITIVETYPE_URI);
+ iLength = FXSYS_wcslen(m_pString);
+ return m_pString;
+ }
+ virtual FDE_CSSPROPERTYVALUE GetEnum() const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_Enum);
+ return m_eEnum;
+ }
+ virtual FX_LPCWSTR GetFuncName() const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_Function);
+ return m_pFunction->GetFuncName();
+ }
+ virtual FX_INT32 CountArgs() const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_Function);
+ return m_pFunction->CountArgs();
+ }
+ virtual IFDE_CSSValue* GetArgs(FX_INT32 index) const
+ {
+ FXSYS_assert(m_eType == FDE_CSSPRIMITIVETYPE_Function);
+ return m_pFunction->GetArgs(index);
+ }
+
+ FDE_CSSPRIMITIVETYPE m_eType;
+ union {
+ FX_ARGB m_dwColor;
+ FX_FLOAT m_fNumber;
+ FX_LPCWSTR m_pString;
+ FDE_CSSPROPERTYVALUE m_eEnum;
+ CFDE_CSSFunction *m_pFunction;
+ };
+};
+typedef CFX_ArrayTemplate<IFDE_CSSPrimitiveValue*> CFDE_CSSPrimitiveArray;
+typedef CFX_ArrayTemplate<IFDE_CSSValue*> CFDE_CSSValueArray;
+class CFDE_CSSValueList : public IFDE_CSSValueList, public CFX_Target
+{
+public:
+ CFDE_CSSValueList(IFX_MEMAllocator *pStaticStore, const CFDE_CSSValueArray &list);
+ virtual FX_INT32 CountValues() const
+ {
+ return m_iCount;
+ }
+ virtual IFDE_CSSValue* GetValue(FX_INT32 index) const
+ {
+ return m_ppList[index];
+ }
+protected:
+ IFDE_CSSValue **m_ppList;
+ FX_INT32 m_iCount;
+};
+class CFDE_CSSValueListParser : public CFX_Target
+{
+public:
+ CFDE_CSSValueListParser(FX_LPCWSTR psz, FX_INT32 iLen, FX_WCHAR separator)
+ : m_Separator(separator), m_pCur(psz), m_pEnd(psz + iLen)
+ {
+ FXSYS_assert(psz != NULL && iLen > 0);
+ }
+ FX_BOOL NextValue(FDE_CSSPRIMITIVETYPE &eType, FX_LPCWSTR &pStart, FX_INT32 &iLength);
+ FX_WCHAR m_Separator;
+protected:
+ FX_INT32 SkipTo(FX_WCHAR wch, FX_BOOL bWSSeparator = FALSE, FX_BOOL bBrContinue = FALSE);
+ FX_LPCWSTR m_pCur;
+ FX_LPCWSTR m_pEnd;
+};
+#ifdef _cplusplus
+extern "C" {
+#endif
+#define FDE_CSSVALUETYPE_MaybeNumber 0x0100
+#define FDE_CSSVALUETYPE_MaybeEnum 0x0200
+#define FDE_CSSVALUETYPE_MaybeURI 0x0400
+#define FDE_CSSVALUETYPE_MaybeString 0x0800
+#define FDE_CSSVALUETYPE_MaybeColor 0x1000
+#define FDE_CSSVALUETYPE_MaybeFunction 0x2000
+#define FDE_IsOnlyValue(type,enum) (((type) & ~(enum)) == FDE_CSSVALUETYPE_Primitive)
+ struct FDE_CSSPROPERTYTABLE {
+ FDE_CSSPROPERTY eName;
+ FX_LPCWSTR pszName;
+ FX_DWORD dwHash;
+ FX_DWORD dwType;
+ };
+ typedef FDE_CSSPROPERTYTABLE const * FDE_LPCCSSPROPERTYTABLE;
+
+ FDE_LPCCSSPROPERTYTABLE FDE_GetCSSPropertyByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ FDE_LPCCSSPROPERTYTABLE FDE_GetCSSPropertyByEnum(FDE_CSSPROPERTY eName);
+ struct FDE_CSSPROPERTYVALUETABLE {
+ FDE_CSSPROPERTYVALUE eName;
+ FX_LPCWSTR pszName;
+ FX_DWORD dwHash;
+ };
+ typedef FDE_CSSPROPERTYVALUETABLE const * FDE_LPCCSSPROPERTYVALUETABLE;
+
+ FDE_LPCCSSPROPERTYVALUETABLE FDE_GetCSSPropertyValueByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ FDE_LPCCSSPROPERTYVALUETABLE FDE_GetCSSPropertyValueByEnum(FDE_CSSPROPERTYVALUE eName);
+ struct FDE_CSSMEDIATYPETABLE {
+ FX_WORD wHash;
+ FX_WORD wValue;
+ };
+ typedef FDE_CSSMEDIATYPETABLE const * FDE_LPCCSSMEDIATYPETABLE;
+ FDE_LPCCSSMEDIATYPETABLE FDE_GetCSSMediaTypeByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ struct FDE_CSSLENGTHUNITTABLE {
+ FX_WORD wHash;
+ FX_WORD wValue;
+ };
+ typedef FDE_CSSLENGTHUNITTABLE const * FDE_LPCCSSLENGTHUNITTABLE;
+ FDE_LPCCSSLENGTHUNITTABLE FDE_GetCSSLengthUnitByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ struct FDE_CSSCOLORTABLE {
+ FX_DWORD dwHash;
+ FX_ARGB dwValue;
+ };
+ typedef FDE_CSSCOLORTABLE const * FDE_LPCCSSCOLORTABLE;
+ FDE_LPCCSSCOLORTABLE FDE_GetCSSColorByName(FX_LPCWSTR pszName, FX_INT32 iLength);
+ struct FDE_CSSPERSUDOTABLE {
+ FDE_CSSPERSUDO eName;
+ FX_LPCWSTR pszName;
+ FX_DWORD dwHash;
+ };
+ typedef FDE_CSSPERSUDOTABLE const * FDE_LPCCSSPERSUDOTABLE;
+
+ FDE_LPCCSSPERSUDOTABLE FDE_GetCSSPersudoByEnum(FDE_CSSPERSUDO ePersudo);
+ FX_BOOL FDE_ParseCSSNumber(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_FLOAT &fValue, FDE_CSSPRIMITIVETYPE &eUnit);
+ FX_BOOL FDE_ParseCSSString(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_INT32 &iOffset, FX_INT32 &iLength);
+ FX_BOOL FDE_ParseCSSColor(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_ARGB &dwColor);
+ FX_BOOL FDE_ParseCSSURI(FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_INT32 &iOffset, FX_INT32 &iLength);
+#ifdef _cplusplus
+};
+#endif
+#endif
diff --git a/xfa/src/fdp/src/css/fde_cssdeclaration.cpp b/xfa/src/fdp/src/css/fde_cssdeclaration.cpp
new file mode 100644
index 0000000000..4abbc5cfa9
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssdeclaration.cpp
@@ -0,0 +1,1193 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_cssdeclaration.h"
+IFDE_CSSValue* CFDE_CSSDeclaration::GetProperty(FDE_CSSPROPERTY eProperty, FX_BOOL &bImportant) const
+{
+ for (FDE_LPCSSPROPERTYHOLDER pHolder = m_pFirstProperty; pHolder; pHolder = pHolder->pNext) {
+ if (pHolder->eProperty == eProperty) {
+ bImportant = pHolder->bImportant;
+ return pHolder->pValue;
+ }
+ }
+ return NULL;
+}
+FX_POSITION CFDE_CSSDeclaration::GetStartPosition() const
+{
+ return (FX_POSITION)m_pFirstProperty;
+}
+void CFDE_CSSDeclaration::GetNextProperty(FX_POSITION &pos, FDE_CSSPROPERTY &eProperty, IFDE_CSSValue *&pValue, FX_BOOL &bImportant) const
+{
+ FDE_LPCSSPROPERTYHOLDER pHolder = (FDE_LPCSSPROPERTYHOLDER)pos;
+ FXSYS_assert(pHolder != NULL);
+ bImportant = pHolder->bImportant;
+ eProperty = (FDE_CSSPROPERTY)pHolder->eProperty;
+ pValue = pHolder->pValue;
+ pos = (FX_POSITION)pHolder->pNext;
+}
+FX_POSITION CFDE_CSSDeclaration::GetStartCustom() const
+{
+ return (FX_POSITION)m_pFirstCustom;
+}
+void CFDE_CSSDeclaration::GetNextCustom(FX_POSITION &pos, CFX_WideString &wsName, CFX_WideString &wsValue) const
+{
+ FDE_LPCSSCUSTOMPROPERTY pProperty = (FDE_LPCSSCUSTOMPROPERTY)pos;
+ if (pProperty == NULL) {
+ return;
+ }
+ wsName = pProperty->pwsName;
+ wsValue = pProperty->pwsValue;
+ pos = (FX_POSITION)pProperty->pNext;
+}
+FX_LPCWSTR CFDE_CSSDeclaration::CopyToLocal(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FXSYS_assert(iValueLen > 0);
+ CFX_MapPtrToPtr *pCache = pArgs->pStringCache;
+ FX_LPVOID pKey = NULL;
+ if (pCache) {
+ FX_LPVOID pszCached = NULL;
+ pKey = (FX_LPVOID)(FX_UINTPTR)FX_HashCode_String_GetW(pszValue, iValueLen, FALSE);
+ if (pCache->Lookup(pKey, pszCached)) {
+ return (FX_LPCWSTR)pszCached;
+ }
+ }
+ FX_LPWSTR psz = (FX_LPWSTR)pArgs->pStaticStore->Alloc((iValueLen + 1) * sizeof(FX_WCHAR));
+ if (psz == NULL) {
+ return NULL;
+ }
+ FXSYS_wcsncpy(psz, pszValue, iValueLen);
+ psz[iValueLen] = '\0';
+ if (pCache) {
+ pCache->SetAt(pKey, psz);
+ }
+ return psz;
+}
+IFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewNumberValue(IFX_MEMAllocator *pStaticStore, FDE_CSSPRIMITIVETYPE eUnit, FX_FLOAT fValue) const
+{
+ static CFDE_CSSPrimitiveValue s_ZeroValue(FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ if (eUnit == FDE_CSSPRIMITIVETYPE_Number && FXSYS_fabs(fValue) < 0.001f) {
+ return &s_ZeroValue;
+ }
+ return FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eUnit, fValue);
+}
+inline IFDE_CSSPrimitiveValue* CFDE_CSSDeclaration::NewEnumValue(IFX_MEMAllocator *pStaticStore, FDE_CSSPROPERTYVALUE eValue) const
+{
+ return FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eValue);
+}
+void CFDE_CSSDeclaration::AddPropertyHolder(IFX_MEMAllocator *pStaticStore, FDE_CSSPROPERTY eProperty, IFDE_CSSValue *pValue, FX_BOOL bImportant)
+{
+ FDE_LPCSSPROPERTYHOLDER pHolder = FDE_NewWith(pStaticStore) FDE_CSSPROPERTYHOLDER;
+ pHolder->bImportant = bImportant;
+ pHolder->eProperty = eProperty;
+ pHolder->pValue = pValue;
+ pHolder->pNext = NULL;
+ if (m_pLastProperty == NULL) {
+ m_pLastProperty = m_pFirstProperty = pHolder;
+ } else {
+ m_pLastProperty->pNext = pHolder;
+ m_pLastProperty = pHolder;
+ }
+}
+FX_BOOL CFDE_CSSDeclaration::AddProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FXSYS_assert(iValueLen > 0);
+ FX_BOOL bImportant = FALSE;
+ if (iValueLen >= 10 && pszValue[iValueLen - 10] == '!'
+ && FX_wcsnicmp((FX_LPCWSTR)L"important", pszValue + iValueLen - 9, 9) == 0) {
+ if ((iValueLen -= 10) == 0) {
+ return FALSE;
+ }
+ bImportant = TRUE;
+ }
+ const FX_DWORD dwType = pArgs->pProperty->dwType;
+ switch (dwType & 0x0F) {
+ case FDE_CSSVALUETYPE_Primitive: {
+ static const FX_DWORD g_ValueGuessOrder[] = {
+ FDE_CSSVALUETYPE_MaybeNumber,
+ FDE_CSSVALUETYPE_MaybeEnum,
+ FDE_CSSVALUETYPE_MaybeColor,
+ FDE_CSSVALUETYPE_MaybeURI,
+ FDE_CSSVALUETYPE_MaybeFunction,
+ FDE_CSSVALUETYPE_MaybeString,
+ };
+ static const FX_INT32 g_ValueGuessCount = sizeof(g_ValueGuessOrder) / sizeof(FX_DWORD);
+ for (FX_INT32 i = 0; i < g_ValueGuessCount; ++i) {
+ const FX_DWORD dwMatch = dwType & g_ValueGuessOrder[i];
+ if (dwMatch == 0) {
+ continue;
+ }
+ IFDE_CSSValue *pCSSValue = NULL;
+ switch (dwMatch) {
+ case FDE_CSSVALUETYPE_MaybeFunction:
+ pCSSValue = ParseFunction(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeNumber:
+ pCSSValue = ParseNumber(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeEnum:
+ pCSSValue = ParseEnum(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeColor:
+ pCSSValue = ParseColor(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeURI:
+ pCSSValue = ParseURI(pArgs, pszValue, iValueLen);
+ break;
+ case FDE_CSSVALUETYPE_MaybeString:
+ pCSSValue = ParseString(pArgs, pszValue, iValueLen);
+ break;
+ default:
+ break;
+ }
+ if (pCSSValue != NULL) {
+ AddPropertyHolder(pArgs->pStaticStore, pArgs->pProperty->eName, pCSSValue, bImportant);
+ return TRUE;
+ }
+ if (FDE_IsOnlyValue(dwType, g_ValueGuessOrder[i])) {
+ return FALSE;
+ }
+ }
+ }
+ break;
+ case FDE_CSSVALUETYPE_Shorthand: {
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ IFDE_CSSValue *pColor, *pStyle, *pWidth;
+ switch (pArgs->pProperty->eName) {
+ case FDE_CSSPROPERTY_Font:
+ return ParseFontProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_Background:
+ return ParseBackgroundProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_ListStyle:
+ return ParseListStyleProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_Border:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderLeftColor, FDE_CSSPROPERTY_BorderLeftStyle, FDE_CSSPROPERTY_BorderLeftWidth);
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderTopWidth);
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderRightColor, FDE_CSSPROPERTY_BorderRightStyle, FDE_CSSPROPERTY_BorderRightWidth);
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderBottomColor, FDE_CSSPROPERTY_BorderBottomStyle, FDE_CSSPROPERTY_BorderBottomWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderLeft:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderLeftColor, FDE_CSSPROPERTY_BorderLeftStyle, FDE_CSSPROPERTY_BorderLeftWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderTop:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderTopWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderRight:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderRightColor, FDE_CSSPROPERTY_BorderRightStyle, FDE_CSSPROPERTY_BorderRightWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderBottom:
+ if (ParseBorderPropoerty(pStaticStore, pszValue, iValueLen, pColor, pStyle, pWidth)) {
+ AddBorderProperty(pStaticStore, pColor, pStyle, pWidth, bImportant,
+ FDE_CSSPROPERTY_BorderBottomColor, FDE_CSSPROPERTY_BorderBottomStyle, FDE_CSSPROPERTY_BorderBottomWidth);
+ return TRUE;
+ }
+ break;
+ case FDE_CSSPROPERTY_Overflow:
+ return ParseOverflowProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_ColumnRule:
+ return ParseColumnRuleProperty(pArgs, pszValue, iValueLen, bImportant);
+ default:
+ break;
+ }
+ }
+ break;
+ case FDE_CSSVALUETYPE_List:
+ switch (pArgs->pProperty->eName) {
+ case FDE_CSSPROPERTY_CounterIncrement:
+ case FDE_CSSPROPERTY_CounterReset:
+ return ParseCounterProperty(pArgs, pszValue, iValueLen, bImportant);
+ case FDE_CSSPROPERTY_Content:
+ return ParseContentProperty(pArgs, pszValue, iValueLen, bImportant);
+ default:
+ return ParseValueListProperty(pArgs, pszValue, iValueLen, bImportant);
+ }
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_CSSDeclaration::AddProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszName, FX_INT32 iNameLen, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FDE_LPCSSCUSTOMPROPERTY pProperty = FDE_NewWith(pArgs->pStaticStore) FDE_CSSCUSTOMPROPERTY;
+ pProperty->pwsName = CopyToLocal(pArgs, pszName, iNameLen);
+ pProperty->pwsValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ pProperty->pNext = NULL;
+ if (m_pLastCustom == NULL) {
+ m_pLastCustom = m_pFirstCustom = pProperty;
+ } else {
+ m_pLastCustom->pNext = pProperty;
+ m_pLastCustom = pProperty;
+ }
+ return TRUE;
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseNumber(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FX_FLOAT fValue;
+ FDE_CSSPRIMITIVETYPE eUnit;
+ if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eUnit)) {
+ return NULL;
+ }
+ return NewNumberValue(pArgs->pStaticStore, eUnit, fValue);
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseEnum(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ return pValue ? NewEnumValue(pArgs->pStaticStore, pValue->eName) : NULL;
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseColor(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FX_ARGB dwColor;
+ if (!FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ return NULL;
+ }
+ return FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseURI(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FX_INT32 iOffset;
+ if (!FDE_ParseCSSURI(pszValue, iValueLen, iOffset, iValueLen)) {
+ return NULL;
+ }
+ if (iValueLen <= 0) {
+ return NULL;
+ }
+ pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen);
+ return pszValue ? FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_URI, pszValue) : NULL;
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseString(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ FX_INT32 iOffset;
+ if (!FDE_ParseCSSString(pszValue, iValueLen, iOffset, iValueLen)) {
+ return NULL;
+ }
+ if (iValueLen <= 0) {
+ return NULL;
+ }
+ pszValue = CopyToLocal(pArgs, pszValue + iOffset, iValueLen);
+ return pszValue ? FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue) : NULL;
+}
+IFDE_CSSValue* CFDE_CSSDeclaration::ParseFunction(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen)
+{
+ if (pszValue[iValueLen - 1] != ')') {
+ return NULL;
+ }
+ FX_INT32 iStartBracket = 0;
+ while (pszValue[iStartBracket] != '(') {
+ if (iStartBracket < iValueLen) {
+ iStartBracket++;
+ } else {
+ return NULL;
+ }
+ }
+ if (iStartBracket == 0) {
+ return NULL;
+ }
+ FX_LPCWSTR pszFuncName = CopyToLocal(pArgs, pszValue, iStartBracket);
+ pszValue += (iStartBracket + 1);
+ iValueLen -= (iStartBracket + 2);
+ CFDE_CSSValueArray argumentArr;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ',');
+ FDE_CSSPRIMITIVETYPE ePrimitiveType;
+ while (parser.NextValue(ePrimitiveType, pszValue, iValueLen)) {
+ switch (ePrimitiveType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pPropertyValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pPropertyValue != NULL) {
+ argumentArr.Add(NewEnumValue(pArgs->pStaticStore, pPropertyValue->eName));
+ continue;
+ }
+ IFDE_CSSValue *pFunctionValue = ParseFunction(pArgs, pszValue, iValueLen);
+ if (pFunctionValue != NULL) {
+ argumentArr.Add(pFunctionValue);
+ continue;
+ }
+ argumentArr.Add(FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, CopyToLocal(pArgs, pszValue, iValueLen)));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, ePrimitiveType)) {
+ argumentArr.Add(NewNumberValue(pArgs->pStaticStore, ePrimitiveType, fValue));
+ }
+ }
+ break;
+ default:
+ argumentArr.Add(FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, CopyToLocal(pArgs, pszValue, iValueLen)));
+ break;
+ }
+ }
+ IFDE_CSSValueList *pArgumentList = FDE_NewWith(pArgs->pStaticStore) CFDE_CSSValueList(pArgs->pStaticStore, argumentArr);
+ CFDE_CSSFunction *pFunction = FDE_NewWith(pArgs->pStaticStore) CFDE_CSSFunction(pszFuncName, pArgumentList);
+ return FDE_NewWith(pArgs->pStaticStore) CFDE_CSSPrimitiveValue(pFunction);
+}
+FX_BOOL CFDE_CSSDeclaration::ParseContentProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator* pStaticStore = (IFX_MEMAllocator*)pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ FDE_CSSPRIMITIVETYPE eType;
+ CFDE_CSSValueArray list;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_URI:
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen)));
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number:
+ return FALSE;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_Normal:
+ case FDE_CSSPROPERTYVALUE_None: {
+ if (list.GetSize() == 0) {
+ list.Add(NewEnumValue(pStaticStore, pValue->eName));
+ } else {
+ return FALSE;
+ }
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_OpenQuote:
+ case FDE_CSSPROPERTYVALUE_CloseQuote:
+ case FDE_CSSPROPERTYVALUE_NoOpenQuote:
+ case FDE_CSSPROPERTYVALUE_NoCloseQuote:
+ list.Add(NewEnumValue(pStaticStore, pValue->eName));
+ break;
+ default:
+ return FALSE;
+ }
+ continue;
+ }
+ IFDE_CSSValue *pFunction = ParseFunction(pArgs, pszValue, iValueLen);
+ if (pFunction != NULL) {
+ list.Add(pFunction);
+ continue;
+ }
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen)));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB:
+ return FALSE;
+ default:
+ break;
+ }
+ }
+ if (list.GetSize() == 0) {
+ return FALSE;
+ }
+ AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list), bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseCounterProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ CFDE_CSSValueArray list;
+ CFDE_CSSValueArray listFull;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ if (list.GetSize() == 1) {
+ list.Add(NewNumberValue(pStaticStore, eType, fValue));
+ listFull.Add(FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list));
+ list.RemoveAll();
+ } else {
+ return FALSE;
+ }
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ if (list.GetSize() == 0) {
+ pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue));
+ } else {
+ listFull.Add(FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list));
+ list.RemoveAll();
+ pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (list.GetSize() == 1) {
+ listFull.Add(FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list));
+ }
+ if (listFull.GetSize() == 0) {
+ return FALSE;
+ }
+ AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, listFull), bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseValueListProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ FX_WCHAR separator = (pArgs->pProperty->eName == FDE_CSSPROPERTY_FontFamily) ? ',' : ' ';
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, separator);
+ const FX_DWORD dwType = pArgs->pProperty->dwType;
+ FDE_CSSPRIMITIVETYPE eType;
+ CFDE_CSSValueArray list;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_Number:
+ if (dwType & FDE_CSSVALUETYPE_MaybeNumber) {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ list.Add(NewNumberValue(pStaticStore, eType, fValue));
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String:
+ if (dwType & FDE_CSSVALUETYPE_MaybeColor) {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor));
+ continue;
+ }
+ }
+ if (dwType & FDE_CSSVALUETYPE_MaybeEnum) {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ list.Add(NewEnumValue(pStaticStore, pValue->eName));
+ continue;
+ }
+ }
+ if (dwType & FDE_CSSVALUETYPE_MaybeString) {
+ pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB:
+ if (dwType & FDE_CSSVALUETYPE_MaybeColor) {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ list.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (list.GetSize() == 0) {
+ return FALSE;
+ }
+ switch (pArgs->pProperty->eName) {
+ case FDE_CSSPROPERTY_BorderColor:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftColor,
+ FDE_CSSPROPERTY_BorderTopColor, FDE_CSSPROPERTY_BorderRightColor, FDE_CSSPROPERTY_BorderBottomColor);
+ case FDE_CSSPROPERTY_BorderStyle:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftStyle,
+ FDE_CSSPROPERTY_BorderTopStyle, FDE_CSSPROPERTY_BorderRightStyle, FDE_CSSPROPERTY_BorderBottomStyle);
+ case FDE_CSSPROPERTY_BorderWidth:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_BorderLeftWidth,
+ FDE_CSSPROPERTY_BorderTopWidth, FDE_CSSPROPERTY_BorderRightWidth, FDE_CSSPROPERTY_BorderBottomWidth);
+ case FDE_CSSPROPERTY_Margin:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_MarginLeft,
+ FDE_CSSPROPERTY_MarginTop, FDE_CSSPROPERTY_MarginRight, FDE_CSSPROPERTY_MarginBottom);
+ case FDE_CSSPROPERTY_Padding:
+ return Add4ValuesProperty(pStaticStore, list, bImportant, FDE_CSSPROPERTY_PaddingLeft,
+ FDE_CSSPROPERTY_PaddingTop, FDE_CSSPROPERTY_PaddingRight, FDE_CSSPROPERTY_PaddingBottom);
+ default: {
+ CFDE_CSSValueList *pList = FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, list);
+ AddPropertyHolder(pStaticStore, pArgs->pProperty->eName, pList, bImportant);
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_CSSDeclaration::Add4ValuesProperty(IFX_MEMAllocator *pStaticStore, const CFDE_CSSValueArray &list, FX_BOOL bImportant, FDE_CSSPROPERTY eLeft, FDE_CSSPROPERTY eTop, FDE_CSSPROPERTY eRight, FDE_CSSPROPERTY eBottom)
+{
+ switch (list.GetSize()) {
+ case 1:
+ AddPropertyHolder(pStaticStore, eLeft, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eRight, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eBottom, list[0], bImportant);
+ return TRUE;
+ case 2:
+ AddPropertyHolder(pStaticStore, eLeft, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eRight, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eBottom, list[0], bImportant);
+ return TRUE;
+ case 3:
+ AddPropertyHolder(pStaticStore, eLeft, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eRight, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eBottom, list[2], bImportant);
+ return TRUE;
+ case 4:
+ AddPropertyHolder(pStaticStore, eLeft, list[3], bImportant);
+ AddPropertyHolder(pStaticStore, eTop, list[0], bImportant);
+ AddPropertyHolder(pStaticStore, eRight, list[1], bImportant);
+ AddPropertyHolder(pStaticStore, eBottom, list[2], bImportant);
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseBorderPropoerty(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR pszValue, FX_INT32 iValueLen, IFDE_CSSValue *&pColor, IFDE_CSSValue *&pStyle, IFDE_CSSValue *&pWidth) const
+{
+ pColor = pStyle = pWidth = NULL;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_Number:
+ if (pWidth == NULL) {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ pWidth = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB:
+ if (pColor == NULL) {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSCOLORTABLE pColorItem = FDE_GetCSSColorByName(pszValue, iValueLen);
+ if (pColorItem != NULL) {
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(pColorItem->dwValue);
+ }
+ continue;
+ }
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue == NULL) {
+ continue;
+ }
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_Transparent:
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Thin:
+ case FDE_CSSPROPERTYVALUE_Thick:
+ case FDE_CSSPROPERTYVALUE_Medium:
+ if (pWidth == NULL) {
+ pWidth = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_None:
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ case FDE_CSSPROPERTYVALUE_Dotted:
+ case FDE_CSSPROPERTYVALUE_Dashed:
+ case FDE_CSSPROPERTYVALUE_Solid:
+ case FDE_CSSPROPERTYVALUE_Double:
+ case FDE_CSSPROPERTYVALUE_Groove:
+ case FDE_CSSPROPERTYVALUE_Ridge:
+ case FDE_CSSPROPERTYVALUE_Inset:
+ case FDE_CSSPROPERTYVALUE_Outset:
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ };
+ break;
+ default:
+ break;
+ }
+ }
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ if (pWidth == NULL) {
+ pWidth = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ }
+ return TRUE;
+}
+void CFDE_CSSDeclaration::AddBorderProperty(IFX_MEMAllocator *pStaticStore, IFDE_CSSValue *pColor, IFDE_CSSValue *pStyle, IFDE_CSSValue *pWidth, FX_BOOL bImportant, FDE_CSSPROPERTY eColor, FDE_CSSPROPERTY eStyle, FDE_CSSPROPERTY eWidth)
+{
+ AddPropertyHolder(pStaticStore, eStyle, pStyle, bImportant);
+ AddPropertyHolder(pStaticStore, eWidth, pWidth, bImportant);
+ AddPropertyHolder(pStaticStore, eColor, pColor, bImportant);
+}
+FX_BOOL CFDE_CSSDeclaration::ParseListStyleProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pType = NULL, *pImage = NULL, *pPosition = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_URI:
+ if (pImage == NULL) {
+ pImage = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue == NULL) {
+ break;
+ }
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_None:
+ if (pImage == NULL) {
+ pImage = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pType == NULL) {
+ pImage = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Inside:
+ case FDE_CSSPROPERTYVALUE_Outside:
+ if (pPosition == NULL) {
+ pPosition = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Disc:
+ case FDE_CSSPROPERTYVALUE_Circle:
+ case FDE_CSSPROPERTYVALUE_Square:
+ case FDE_CSSPROPERTYVALUE_Decimal:
+ case FDE_CSSPROPERTYVALUE_DecimalLeadingZero:
+ case FDE_CSSPROPERTYVALUE_LowerRoman:
+ case FDE_CSSPROPERTYVALUE_UpperRoman:
+ case FDE_CSSPROPERTYVALUE_LowerGreek:
+ case FDE_CSSPROPERTYVALUE_LowerLatin:
+ case FDE_CSSPROPERTYVALUE_UpperLatin:
+ case FDE_CSSPROPERTYVALUE_Armenian:
+ case FDE_CSSPROPERTYVALUE_Georgian:
+ case FDE_CSSPROPERTYVALUE_LowerAlpha:
+ case FDE_CSSPROPERTYVALUE_UpperAlpha:
+ if (pType == NULL) {
+ pType = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ };
+ break;
+ default:
+ break;
+ }
+ }
+ if (pPosition == NULL) {
+ pPosition = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Outside);
+ }
+ if (pImage == NULL) {
+ pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ if (pType == NULL) {
+ pType = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStylePosition, pPosition, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStyleImage, pImage, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ListStyleType, pType, bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseBackgroundProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pColor = NULL, *pImage = NULL, *pRepeat = NULL;
+ IFDE_CSSPrimitiveValue *pPosX = NULL, *pPosY = NULL, *pAttachment = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_URI:
+ if (pImage == NULL) {
+ pImage = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ break;
+ }
+ if (pPosX == NULL) {
+ pPosX = NewNumberValue(pStaticStore, eType, fValue);
+ } else if (pPosY == NULL) {
+ pPosY = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_None:
+ if (pImage == NULL) {
+ pImage = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Transparent:
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Fixed:
+ case FDE_CSSPROPERTYVALUE_Scroll:
+ if (pAttachment == NULL) {
+ pAttachment = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Repeat:
+ case FDE_CSSPROPERTYVALUE_RepeatX:
+ case FDE_CSSPROPERTYVALUE_RepeatY:
+ case FDE_CSSPROPERTYVALUE_NoRepeat:
+ if (pRepeat == NULL) {
+ pRepeat = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Left:
+ case FDE_CSSPROPERTYVALUE_Right:
+ if (pPosX == NULL) {
+ pPosX = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Top:
+ case FDE_CSSPROPERTYVALUE_Bottom:
+ if (pPosY == NULL) {
+ pPosX = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Center:
+ if (pPosX == NULL) {
+ pPosX = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pPosY == NULL) {
+ pPosX = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ FDE_LPCCSSCOLORTABLE pColorItem = FDE_GetCSSColorByName(pszValue, iValueLen);
+ if (pColorItem != NULL)
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(pColorItem->dwValue);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB:
+ if (pColor == NULL) {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pColor == NULL) {
+ pColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ if (pImage == NULL) {
+ pImage = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ if (pRepeat == NULL) {
+ pRepeat = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Repeat);
+ }
+ if (pAttachment == NULL) {
+ pAttachment = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Scroll);
+ }
+ if (pPosX == NULL) {
+ pPosX = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ pPosY = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ } else if (pPosY == NULL) {
+ pPosY = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, 0.0f);
+ }
+ CFDE_CSSValueArray position;
+ position.Add(pPosX);
+ position.Add(pPosY);
+ CFDE_CSSValueList *pPosList = FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, position);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundColor, pColor, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundImage, pImage, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundRepeat, pRepeat, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundPosition, pPosList, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_BackgroundAttachment, pAttachment, bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseFontProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, '/');
+ IFDE_CSSPrimitiveValue *pStyle = NULL, *pVariant = NULL, *pWeight = NULL;
+ IFDE_CSSPrimitiveValue *pFontSize = NULL, *pLineHeight = NULL;
+ CFDE_CSSValueArray familyList;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_XxSmall:
+ case FDE_CSSPROPERTYVALUE_XSmall:
+ case FDE_CSSPROPERTYVALUE_Small:
+ case FDE_CSSPROPERTYVALUE_Medium:
+ case FDE_CSSPROPERTYVALUE_Large:
+ case FDE_CSSPROPERTYVALUE_XLarge:
+ case FDE_CSSPROPERTYVALUE_XxLarge:
+ case FDE_CSSPROPERTYVALUE_Smaller:
+ case FDE_CSSPROPERTYVALUE_Larger:
+ if (pFontSize == NULL) {
+ pFontSize = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ case FDE_CSSPROPERTYVALUE_Bold:
+ case FDE_CSSPROPERTYVALUE_Bolder:
+ case FDE_CSSPROPERTYVALUE_Lighter:
+ if (pWeight == NULL) {
+ pWeight = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ case FDE_CSSPROPERTYVALUE_Italic:
+ case FDE_CSSPROPERTYVALUE_Oblique:
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ case FDE_CSSPROPERTYVALUE_SmallCaps:
+ if (pVariant == NULL) {
+ pVariant = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ case FDE_CSSPROPERTYVALUE_Normal:
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pVariant == NULL) {
+ pVariant = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pWeight == NULL) {
+ pWeight = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pFontSize == NULL) {
+ pFontSize = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pLineHeight == NULL) {
+ pLineHeight = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ continue;
+ default:
+ break;
+ }
+ }
+ if (pFontSize != NULL) {
+ familyList.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(eType, CopyToLocal(pArgs, pszValue, iValueLen)));
+ }
+ parser.m_Separator = ',';
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (!FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ break;
+ }
+ if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ switch ((FX_INT32)fValue) {
+ case 100:
+ case 200:
+ case 300:
+ case 400:
+ case 500:
+ case 600:
+ case 700:
+ case 800:
+ case 900:
+ if (pWeight == NULL) {
+ pWeight = NewNumberValue(pStaticStore, FDE_CSSPRIMITIVETYPE_Number, fValue);
+ }
+ continue;
+ }
+ }
+ if (pFontSize == NULL) {
+ pFontSize = NewNumberValue(pStaticStore, eType, fValue);
+ } else if (pLineHeight == NULL) {
+ pLineHeight = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pStyle == NULL) {
+ pStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
+ }
+ if (pVariant == NULL) {
+ pVariant = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
+ }
+ if (pWeight == NULL) {
+ pWeight = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
+ }
+ if (pFontSize == NULL) {
+ pFontSize = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium);
+ }
+ if (pLineHeight == NULL) {
+ pLineHeight = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Normal);
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontStyle, pStyle, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontVariant, pVariant, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontWeight, pWeight, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontSize, pFontSize, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_LineHeight, pLineHeight, bImportant);
+ if (familyList.GetSize() > 0) {
+ CFDE_CSSValueList *pList = FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, familyList);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_FontFamily, pList, bImportant);
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseColumnRuleProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pColumnRuleWidth = NULL;
+ IFDE_CSSPrimitiveValue *pColumnRuleStyle = NULL;
+ IFDE_CSSPrimitiveValue *pColumnRuleColor = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSPROPERTYVALUE_None:
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ case FDE_CSSPROPERTYVALUE_Dotted:
+ case FDE_CSSPROPERTYVALUE_Dashed:
+ case FDE_CSSPROPERTYVALUE_Solid:
+ case FDE_CSSPROPERTYVALUE_Double:
+ case FDE_CSSPROPERTYVALUE_Groove:
+ case FDE_CSSPROPERTYVALUE_Ridge:
+ case FDE_CSSPROPERTYVALUE_Inset:
+ case FDE_CSSPROPERTYVALUE_Outset:
+ if (pColumnRuleStyle == NULL) {
+ pColumnRuleStyle = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Transparent:
+ if (pColumnRuleColor == NULL) {
+ pColumnRuleColor = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Thin:
+ case FDE_CSSPROPERTYVALUE_Medium:
+ case FDE_CSSPROPERTYVALUE_Thick:
+ if (pColumnRuleWidth == NULL) {
+ pColumnRuleWidth = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ continue;
+ }
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor) && pColumnRuleColor == NULL) {
+ pColumnRuleColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)dwColor);
+ continue;
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType) && pColumnRuleWidth == NULL) {
+ pColumnRuleWidth = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB: {
+ FX_ARGB dwColor;
+ if (pColumnRuleColor == NULL && FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pColumnRuleColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)dwColor);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pColumnRuleColor == NULL && pColumnRuleStyle == NULL && pColumnRuleWidth == NULL) {
+ return FALSE;
+ }
+ if (pColumnRuleStyle == NULL) {
+ pColumnRuleStyle = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_None);
+ }
+ if (pColumnRuleWidth == NULL) {
+ pColumnRuleWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Medium);
+ }
+ if (pColumnRuleColor == NULL) {
+ pColumnRuleColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue((FX_ARGB)0);
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleStyle, pColumnRuleStyle, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleWidth, pColumnRuleWidth, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnRuleColor, pColumnRuleColor, bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseTextEmphasisProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ CFDE_CSSValueArray arrEmphasisStyle;
+ FDE_CSSPRIMITIVETYPE eType;
+ IFDE_CSSPrimitiveValue *pEmphasisColor = NULL;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ arrEmphasisStyle.Add(NewEnumValue(pStaticStore, pValue->eName));
+ continue;
+ }
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pEmphasisColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+ continue;
+ }
+ pszValue = CopyToLocal(pArgs, pszValue, iValueLen);
+ arrEmphasisStyle.Add(FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(FDE_CSSPRIMITIVETYPE_String, pszValue));
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_RGB: {
+ FX_ARGB dwColor;
+ if (FDE_ParseCSSColor(pszValue, iValueLen, dwColor)) {
+ pEmphasisColor = FDE_NewWith(pStaticStore) CFDE_CSSPrimitiveValue(dwColor);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (arrEmphasisStyle.GetSize() != 0) {
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_TextEmphasisStyle, FDE_NewWith(pStaticStore) CFDE_CSSValueList(pStaticStore, arrEmphasisStyle), bImportant);
+ }
+ if (pEmphasisColor != NULL) {
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_TextEmphasisColor, pEmphasisColor, bImportant);
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseColumnsProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pColumnWidth = NULL;
+ IFDE_CSSPrimitiveValue *pColumnCount = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue == NULL && pValue->eName == FDE_CSSPROPERTYVALUE_Auto) {
+ pColumnWidth = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number: {
+ FX_FLOAT fValue;
+ if (FDE_ParseCSSNumber(pszValue, iValueLen, fValue, eType)) {
+ switch (eType) {
+ case FDE_CSSPRIMITIVETYPE_Number:
+ if (pColumnCount == NULL) {
+ pColumnCount = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ break;
+ default:
+ if (pColumnWidth == NULL) {
+ pColumnWidth = NewNumberValue(pStaticStore, eType, fValue);
+ }
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pColumnWidth == NULL && pColumnCount == NULL) {
+ return FALSE;
+ } else if (pColumnWidth == NULL) {
+ pColumnWidth = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Auto);
+ } else if (pColumnCount == NULL) {
+ pColumnCount = NewEnumValue(pStaticStore, FDE_CSSPROPERTYVALUE_Auto);
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnWidth, pColumnWidth, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_ColumnCount, pColumnCount, bImportant);
+ return TRUE;
+}
+FX_BOOL CFDE_CSSDeclaration::ParseOverflowProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant)
+{
+ IFX_MEMAllocator *pStaticStore = pArgs->pStaticStore;
+ CFDE_CSSValueListParser parser(pszValue, iValueLen, ' ');
+ IFDE_CSSPrimitiveValue *pOverflowX = NULL;
+ IFDE_CSSPrimitiveValue *pOverflowY = NULL;
+ FDE_CSSPRIMITIVETYPE eType;
+ while (parser.NextValue(eType, pszValue, iValueLen)) {
+ if (eType == FDE_CSSPRIMITIVETYPE_String) {
+ FDE_LPCCSSPROPERTYVALUETABLE pValue = FDE_GetCSSPropertyValueByName(pszValue, iValueLen);
+ if (pValue != NULL) {
+ switch (pValue->eName) {
+ case FDE_CSSOVERFLOW_Visible:
+ case FDE_CSSOVERFLOW_Hidden:
+ case FDE_CSSOVERFLOW_Scroll:
+ case FDE_CSSOVERFLOW_Auto:
+ case FDE_CSSOVERFLOW_NoDisplay:
+ case FDE_CSSOVERFLOW_NoContent:
+ if (pOverflowX != NULL && pOverflowY != NULL) {
+ return FALSE;
+ } else if (pOverflowX == NULL) {
+ pOverflowX = NewEnumValue(pStaticStore, pValue->eName);
+ } else if (pOverflowY == NULL) {
+ pOverflowY = NewEnumValue(pStaticStore, pValue->eName);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ if (pOverflowX == NULL && pOverflowY == NULL) {
+ return FALSE;
+ } else if (pOverflowY == NULL) {
+ pOverflowY = NewEnumValue(pStaticStore, pOverflowX->GetEnum());
+ }
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowX, pOverflowX, bImportant);
+ AddPropertyHolder(pStaticStore, FDE_CSSPROPERTY_OverflowY, pOverflowY, bImportant);
+ return TRUE;
+}
diff --git a/xfa/src/fdp/src/css/fde_cssdeclaration.h b/xfa/src/fdp/src/css/fde_cssdeclaration.h
new file mode 100644
index 0000000000..ca0add9dea
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssdeclaration.h
@@ -0,0 +1,70 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSDECLARATION
+#define _FDE_CSSDECLARATION
+#include "fde_cssdatatable.h"
+typedef struct _FDE_CSSPROPERTYHOLDER : public CFX_Target {
+ FX_INT16 eProperty;
+ FX_INT16 bImportant;
+ IFDE_CSSValue *pValue;
+ _FDE_CSSPROPERTYHOLDER *pNext;
+} FDE_CSSPROPERTYHOLDER, *FDE_LPCSSPROPERTYHOLDER;
+typedef struct _FDE_CSSCUSTOMPROPERTY : public CFX_Target {
+ FX_LPCWSTR pwsName;
+ FX_LPCWSTR pwsValue;
+ _FDE_CSSCUSTOMPROPERTY *pNext;
+} FDE_CSSCUSTOMPROPERTY, * FDE_LPCSSCUSTOMPROPERTY;
+typedef struct _FDE_CSSPROPERTYARGS : public CFX_Target {
+ IFX_MEMAllocator *pStaticStore;
+ CFX_MapPtrToPtr *pStringCache;
+ FDE_LPCCSSPROPERTYTABLE pProperty;
+} FDE_CSSPROPERTYARGS;
+typedef FDE_CSSPROPERTYARGS const * FDE_LPCCSSPROPERTYARGS;
+class CFDE_CSSDeclaration : public IFDE_CSSDeclaration, public CFX_Target
+{
+public:
+ CFDE_CSSDeclaration() : m_pFirstProperty(NULL), m_pLastProperty(NULL), m_pFirstCustom(NULL), m_pLastCustom(NULL) { }
+ virtual IFDE_CSSValue* GetProperty(FDE_CSSPROPERTY eProperty, FX_BOOL &bImportant) const;
+ virtual FX_POSITION GetStartPosition() const;
+ virtual void GetNextProperty(FX_POSITION &pos, FDE_CSSPROPERTY &eProperty, IFDE_CSSValue *&pValue, FX_BOOL &bImportant) const;
+ virtual FX_POSITION GetStartCustom() const;
+ virtual void GetNextCustom(FX_POSITION &pos, CFX_WideString &wsName, CFX_WideString &wsValue) const;
+ FX_BOOL AddProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ FX_BOOL AddProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszName, FX_INT32 iNameLen, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+protected:
+ FX_BOOL ParseTextEmphasisProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseColumnsProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseColumnRuleProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseOverflowProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseFontProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseBackgroundProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseListStyleProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseBorderPropoerty(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR pszValue, FX_INT32 iValueLen,
+ IFDE_CSSValue *&pColor, IFDE_CSSValue *&pStyle, IFDE_CSSValue *&pWidth) const;
+ void AddBorderProperty(IFX_MEMAllocator *pStaticStore, IFDE_CSSValue *pColor, IFDE_CSSValue *pStyle, IFDE_CSSValue *pWidth, FX_BOOL bImportant,
+ FDE_CSSPROPERTY eColor, FDE_CSSPROPERTY eStyle, FDE_CSSPROPERTY eWidth);
+ FX_BOOL ParseContentProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseCounterProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL ParseValueListProperty(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen, FX_BOOL bImportant);
+ FX_BOOL Add4ValuesProperty(IFX_MEMAllocator *pStaticStore, const CFDE_CSSValueArray &list, FX_BOOL bImportant,
+ FDE_CSSPROPERTY eLeft, FDE_CSSPROPERTY eTop, FDE_CSSPROPERTY eRight, FDE_CSSPROPERTY eBottom);
+ IFDE_CSSValue* ParseNumber(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseEnum(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseColor(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseURI(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseString(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ IFDE_CSSValue* ParseFunction(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ FX_LPCWSTR CopyToLocal(FDE_LPCCSSPROPERTYARGS pArgs, FX_LPCWSTR pszValue, FX_INT32 iValueLen);
+ void AddPropertyHolder(IFX_MEMAllocator *pStaticStore, FDE_CSSPROPERTY eProperty, IFDE_CSSValue *pValue, FX_BOOL bImportant);
+ IFDE_CSSPrimitiveValue* NewNumberValue(IFX_MEMAllocator *pStaticStore, FDE_CSSPRIMITIVETYPE eUnit, FX_FLOAT fValue) const;
+ IFDE_CSSPrimitiveValue* NewEnumValue(IFX_MEMAllocator *pStaticStore, FDE_CSSPROPERTYVALUE eValue) const;
+ FDE_LPCSSPROPERTYHOLDER m_pFirstProperty;
+ FDE_LPCSSPROPERTYHOLDER m_pLastProperty;
+ FDE_LPCSSCUSTOMPROPERTY m_pFirstCustom;
+ FDE_LPCSSCUSTOMPROPERTY m_pLastCustom;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_cssstyleselector.cpp b/xfa/src/fdp/src/css/fde_cssstyleselector.cpp
new file mode 100644
index 0000000000..6372a8cb20
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssstyleselector.cpp
@@ -0,0 +1,1715 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_csscache.h"
+#include "fde_cssdeclaration.h"
+#include "fde_cssstyleselector.h"
+FX_INT32 CFDE_CSSCounterStyle::FindIndex(FX_LPCWSTR pszIdentifier)
+{
+ FX_INT32 iCount = m_arrCounterData.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ if (FXSYS_wcscmp(pszIdentifier, m_arrCounterData.ElementAt(i).m_pszIdent) == 0) {
+ return i;
+ }
+ }
+ return -1;
+}
+void CFDE_CSSCounterStyle::DoUpdateIndex(IFDE_CSSValueList *pList)
+{
+ if (pList == NULL) {
+ return;
+ }
+ FX_INT32 iCount = pList->CountValues();
+ FX_FLOAT fDefValue = 1.0;
+ FX_BOOL bDefIncrement = TRUE;
+ if (pList == m_pCounterReset) {
+ fDefValue = 0.0;
+ bDefIncrement = FALSE;
+ }
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ IFDE_CSSValueList *pCounter = (IFDE_CSSValueList*)pList->GetValue(i);
+ FX_INT32 iLen;
+ FX_LPCWSTR pszIdentifier = ((IFDE_CSSPrimitiveValue*)(pCounter->GetValue(0)))->GetString(iLen);
+ FX_FLOAT fValue = fDefValue;
+ if (pCounter->CountValues() > 1) {
+ fValue = ((IFDE_CSSPrimitiveValue*)(pCounter->GetValue(1)))->GetFloat();
+ }
+ FX_INT32 iIndex = FindIndex(pszIdentifier);
+ if (iIndex == -1) {
+ FDE_CSSCOUNTERDATA data;
+ data.m_pszIdent = pszIdentifier;
+ if (bDefIncrement) {
+ data.m_bIncrement = TRUE;
+ data.m_iIncVal = (FX_INT32)fValue;
+ } else {
+ data.m_iResetVal = (FX_INT32)fValue;
+ data.m_bReset = TRUE;
+ }
+ m_arrCounterData.Add(data);
+ } else {
+ FDE_CSSCOUNTERDATA &data = m_arrCounterData.ElementAt(iIndex);
+ if (bDefIncrement) {
+ data.m_bIncrement = TRUE;
+ data.m_iIncVal += (FX_INT32)fValue;
+ } else {
+ data.m_bReset = TRUE;
+ data.m_iResetVal = (FX_INT32)fValue;
+ }
+ }
+ }
+}
+void CFDE_CSSCounterStyle::UpdateIndex()
+{
+ if (!m_bIndexDirty) {
+ return;
+ }
+ m_arrCounterData.RemoveAll();
+ DoUpdateIndex(m_pCounterInc);
+ DoUpdateIndex(m_pCounterReset);
+ m_bIndexDirty = FALSE;
+}
+FDE_CSSTEXTEMPHASISMARK CFDE_CSSComputedStyle::GetTextEmphasisMark() const
+{
+ if (m_InheritedData.m_eTextEmphasisMark != FDE_CSSTEXTEMPHASISMARK_Auto) {
+ return (FDE_CSSTEXTEMPHASISMARK)m_InheritedData.m_eTextEmphasisMark;
+ }
+ if (m_InheritedData.m_eWritingMode == FDE_CSSWRITINGMODE_HorizontalTb) {
+ return FDE_CSSTEXTEMPHASISMARK_Dot;
+ }
+ return FDE_CSSTEXTEMPHASISMARK_Sesame;
+}
+_FDE_CSSRULEDATA::_FDE_CSSRULEDATA(IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl, FX_DWORD dwPos)
+ : pSelector(pSel)
+ , pDeclaration(pDecl)
+ , dwPriority(dwPos)
+ , pNext(NULL)
+{
+ static const FX_DWORD s_Specific[5] = {0x00010000, 0x00010000, 0x00100000, 0x00100000, 0x01000000};
+ for (; pSel != NULL; pSel = pSel->GetNextSelector()) {
+ FDE_CSSSELECTORTYPE eType = pSel->GetType();
+ if (eType > FDE_CSSSELECTORTYPE_Descendant || pSel->GetNameHash() != FDE_CSSUNIVERSALHASH) {
+ dwPriority += s_Specific[eType];
+ }
+ }
+}
+void CFDE_CSSRuleCollection::Clear()
+{
+ m_IDRules.RemoveAll();
+ m_TagRules.RemoveAll();
+ m_ClassRules.RemoveAll();
+ m_pUniversalRules = NULL;
+ m_pStaticStore = NULL;
+ m_iSelectors = 0;
+}
+void CFDE_CSSRuleCollection::AddRulesFrom(const CFDE_CSSStyleSheetArray &sheets, FX_DWORD dwMediaList, IFX_FontMgr *pFontMgr)
+{
+ FX_INT32 iSheets = sheets.GetSize();
+ for (FX_INT32 i = 0; i < iSheets; ++i) {
+ IFDE_CSSStyleSheet *pSheet = sheets.GetAt(i);
+ if (FX_DWORD dwMatchMedia = pSheet->GetMediaList() & dwMediaList) {
+ FX_INT32 iRules = pSheet->CountRules();
+ for (FX_INT32 j = 0; j < iRules; j++) {
+ AddRulesFrom(pSheet, pSheet->GetRule(j), dwMatchMedia, pFontMgr);
+ }
+ }
+ }
+}
+void CFDE_CSSRuleCollection::AddRulesFrom(IFDE_CSSStyleSheet *pStyleSheet, IFDE_CSSRule *pRule, FX_DWORD dwMediaList, IFX_FontMgr *pFontMgr)
+{
+ switch (pRule->GetType()) {
+ case FDE_CSSRULETYPE_Style: {
+ IFDE_CSSStyleRule *pStyleRule = (IFDE_CSSStyleRule*)pRule;
+ IFDE_CSSDeclaration *pDeclaration = pStyleRule->GetDeclaration();
+ FX_INT32 iSelectors = pStyleRule->CountSelectorLists();
+ for (FX_INT32 i = 0; i < iSelectors; ++i) {
+ IFDE_CSSSelector *pSelector = pStyleRule->GetSelectorList(i);
+ if (pSelector->GetType() == FDE_CSSSELECTORTYPE_Persudo) {
+ FDE_LPCSSRULEDATA pData = NewRuleData(pSelector, pDeclaration);
+ AddRuleTo(m_pPersudoRules, pData);
+ continue;
+ }
+ if (pSelector->GetNameHash() != FDE_CSSUNIVERSALHASH) {
+ AddRuleTo(m_TagRules, pSelector->GetNameHash(), pSelector, pDeclaration);
+ continue;
+ }
+ IFDE_CSSSelector *pNext = pSelector->GetNextSelector();
+ if (pNext == NULL) {
+ FDE_LPCSSRULEDATA pData = NewRuleData(pSelector, pDeclaration);
+ AddRuleTo(m_pUniversalRules, pData);
+ continue;
+ }
+ switch (pNext->GetType()) {
+ case FDE_CSSSELECTORTYPE_ID:
+ AddRuleTo(m_IDRules, pNext->GetNameHash(), pSelector, pDeclaration);
+ break;
+ case FDE_CSSSELECTORTYPE_Class:
+ AddRuleTo(m_ClassRules, pNext->GetNameHash(), pSelector, pDeclaration);
+ break;
+ case FDE_CSSSELECTORTYPE_Descendant:
+ case FDE_CSSSELECTORTYPE_Element:
+ AddRuleTo(m_pUniversalRules, NewRuleData(pSelector, pDeclaration));
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ }
+ }
+ break;
+ case FDE_CSSRULETYPE_Media: {
+ IFDE_CSSMediaRule *pMediaRule = (IFDE_CSSMediaRule*)pRule;
+ if (pMediaRule->GetMediaList() & dwMediaList) {
+ FX_INT32 iRules = pMediaRule->CountRules();
+ for (FX_INT32 i = 0; i < iRules; ++i) {
+ AddRulesFrom(pStyleSheet, pMediaRule->GetRule(i), dwMediaList, pFontMgr);
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+void CFDE_CSSRuleCollection::AddRuleTo(CFX_MapPtrToPtr &map, FX_DWORD dwKey, IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl)
+{
+ FX_LPVOID pKey = (FX_LPVOID)(FX_UINTPTR)dwKey;
+ FDE_LPCSSRULEDATA pData = NewRuleData(pSel, pDecl);
+ FDE_LPCSSRULEDATA pList = NULL;
+ if (!map.Lookup(pKey, (FX_LPVOID&)pList)) {
+ map.SetAt(pKey, pData);
+ } else if (AddRuleTo(pList, pData)) {
+ map.SetAt(pKey, pList);
+ }
+}
+inline FX_BOOL CFDE_CSSRuleCollection::AddRuleTo(FDE_LPCSSRULEDATA &pList, FDE_LPCSSRULEDATA pData)
+{
+ if (pList == NULL) {
+ pList = pData;
+ return TRUE;
+ } else {
+ pData->pNext = pList->pNext;
+ pList->pNext = pData;
+ return FALSE;
+ }
+}
+inline FDE_LPCSSRULEDATA CFDE_CSSRuleCollection::NewRuleData(IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl)
+{
+ return FDE_NewWith(m_pStaticStore) FDE_CSSRULEDATA(pSel, pDecl, ++m_iSelectors);
+}
+IFDE_CSSStyleSelector* IFDE_CSSStyleSelector::Create()
+{
+ return FDE_New CFDE_CSSStyleSelector;
+}
+CFDE_CSSStyleSelector::CFDE_CSSStyleSelector()
+ : m_pFontMgr(NULL)
+ , m_fDefFontSize(12.0f)
+ , m_pRuleDataStore(NULL)
+ , m_pInlineStyleStore(NULL)
+ , m_pFixedStyleStore(NULL)
+ , m_pAccelerator(NULL)
+{
+ m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_High] = FDE_CSSSTYLESHEETGROUP_Author;
+ m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_Mid] = FDE_CSSSTYLESHEETGROUP_User;
+ m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_Low] = FDE_CSSSTYLESHEETGROUP_UserAgent;
+}
+CFDE_CSSStyleSelector::~CFDE_CSSStyleSelector()
+{
+ Reset();
+ if (m_pInlineStyleStore != NULL) {
+ m_pInlineStyleStore->Release();
+ }
+ if (m_pFixedStyleStore != NULL) {
+ m_pFixedStyleStore->Release();
+ }
+ if (m_pAccelerator != NULL) {
+ FDE_Delete m_pAccelerator;
+ }
+}
+void CFDE_CSSStyleSelector::SetFontMgr(IFX_FontMgr *pFontMgr)
+{
+ m_pFontMgr = pFontMgr;
+}
+void CFDE_CSSStyleSelector::SetDefFontSize(FX_FLOAT fFontSize)
+{
+ FXSYS_assert(fFontSize > 0);
+ m_fDefFontSize = fFontSize;
+}
+IFDE_CSSAccelerator* CFDE_CSSStyleSelector::InitAccelerator()
+{
+ if (m_pAccelerator == NULL) {
+ m_pAccelerator = FDE_New CFDE_CSSAccelerator;
+ FXSYS_assert(m_pAccelerator != NULL);
+ }
+ m_pAccelerator->Clear();
+ return m_pAccelerator;
+}
+IFDE_CSSComputedStyle* CFDE_CSSStyleSelector::CreateComputedStyle(IFDE_CSSComputedStyle *pParentStyle)
+{
+ if (m_pFixedStyleStore == NULL) {
+ m_pFixedStyleStore = FX_CreateAllocator(FX_ALLOCTYPE_Fixed, 16, sizeof(CFDE_CSSComputedStyle));
+ FXSYS_assert(m_pFixedStyleStore != NULL);
+ }
+ CFDE_CSSComputedStyle *pStyle = FDE_NewWith(m_pFixedStyleStore) CFDE_CSSComputedStyle(m_pFixedStyleStore);
+ if (pParentStyle) {
+ pStyle->m_InheritedData = ((CFDE_CSSComputedStyle*)pParentStyle)->m_InheritedData;
+ } else {
+ pStyle->m_InheritedData.Reset();
+ }
+ pStyle->m_NonInheritedData.Reset();
+ return pStyle;
+}
+FX_BOOL CFDE_CSSStyleSelector::SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType, IFDE_CSSStyleSheet *pSheet)
+{
+ FXSYS_assert(eType < FDE_CSSSTYLESHEETGROUP_MAX);
+ CFDE_CSSStyleSheetArray &dest = m_SheetGroups[eType];
+ dest.RemoveAt(0, dest.GetSize());
+ if (pSheet != NULL) {
+ dest.Add(pSheet);
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_CSSStyleSelector::SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType, const CFDE_CSSStyleSheetArray *pArray)
+{
+ FXSYS_assert(eType < FDE_CSSSTYLESHEETGROUP_MAX);
+ CFDE_CSSStyleSheetArray &dest = m_SheetGroups[eType];
+ if (pArray == NULL) {
+ dest.RemoveAt(0, dest.GetSize());
+ } else {
+ dest.Copy(*pArray);
+ }
+ return TRUE;
+}
+void CFDE_CSSStyleSelector::SetStylePriority(FDE_CSSSTYLESHEETGROUP eType, FDE_CSSSTYLESHEETPRIORITY ePriority)
+{
+ m_ePriorities[ePriority] = eType;
+}
+void CFDE_CSSStyleSelector::UpdateStyleIndex(FX_DWORD dwMediaList)
+{
+ Reset();
+ m_pRuleDataStore = FX_CreateAllocator(FX_ALLOCTYPE_Static, 1024, 0);
+ FXSYS_assert(m_pRuleDataStore != NULL);
+ for (FX_INT32 iGroup = 0; iGroup < FDE_CSSSTYLESHEETGROUP_MAX; ++iGroup) {
+ CFDE_CSSRuleCollection &rules = m_RuleCollection[iGroup];
+ rules.m_pStaticStore = m_pRuleDataStore;
+ rules.AddRulesFrom(m_SheetGroups[iGroup], dwMediaList, m_pFontMgr);
+ }
+}
+void CFDE_CSSStyleSelector::Reset()
+{
+ for (FX_INT32 iGroup = 0; iGroup < FDE_CSSSTYLESHEETGROUP_MAX; ++iGroup) {
+ m_RuleCollection[iGroup].Clear();
+ }
+ if (m_pRuleDataStore != NULL) {
+ m_pRuleDataStore->Release();
+ m_pRuleDataStore = NULL;
+ }
+}
+FX_INT32 CFDE_CSSStyleSelector::MatchDeclarations(IFDE_CSSTagProvider *pTag, CFDE_CSSDeclarationArray &matchedDecls, FDE_CSSPERSUDO ePersudoType)
+{
+ FXSYS_assert(m_pAccelerator != NULL && pTag != NULL);
+ FDE_LPCSSTAGCACHE pCache = m_pAccelerator->GetTopElement();
+ FXSYS_assert(pCache != NULL && pCache->GetTag() == pTag);
+ matchedDecls.RemoveAt(0, matchedDecls.GetSize());
+ for (FX_INT32 ePriority = FDE_CSSSTYLESHEETPRIORITY_MAX - 1; ePriority >= 0; --ePriority) {
+ FDE_CSSSTYLESHEETGROUP eGroup = m_ePriorities[ePriority];
+ CFDE_CSSRuleCollection &rules = m_RuleCollection[eGroup];
+ if (rules.CountSelectors() == 0) {
+ continue;
+ }
+ if (ePersudoType == FDE_CSSPERSUDO_NONE) {
+ MatchRules(pCache, rules.GetUniversalRuleData(), ePersudoType);
+ if (pCache->HashTag()) {
+ MatchRules(pCache, rules.GetTagRuleData(pCache->HashTag()), ePersudoType);
+ }
+ FX_INT32 iCount = pCache->CountHashClass();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ pCache->SetClassIndex(i);
+ MatchRules(pCache, rules.GetClassRuleData(pCache->HashClass()), ePersudoType);
+ }
+ } else {
+ MatchRules(pCache, rules.GetPersudoRuleData(), ePersudoType);
+ }
+ if (m_MatchedRules.GetSize() > 0) {
+ SortRulesTo(matchedDecls);
+ m_MatchedRules.RemoveAt(0, m_MatchedRules.GetSize());
+ }
+ }
+ return matchedDecls.GetSize();
+}
+inline void CFDE_CSSStyleSelector::MatchRules(FDE_LPCSSTAGCACHE pCache, FDE_LPCSSRULEDATA pList, FDE_CSSPERSUDO ePersudoType)
+{
+ while (pList != NULL) {
+ if (MatchSelector(pCache, pList->pSelector, ePersudoType)) {
+ m_MatchedRules.Add(pList);
+ }
+ pList = pList->pNext;
+ }
+}
+FX_BOOL CFDE_CSSStyleSelector::MatchSelector(FDE_LPCSSTAGCACHE pCache, IFDE_CSSSelector *pSel, FDE_CSSPERSUDO ePersudoType)
+{
+ FX_DWORD dwHash;
+ while (pSel != NULL && pCache != NULL) {
+ switch (pSel->GetType()) {
+ case FDE_CSSSELECTORTYPE_Descendant:
+ dwHash = pSel->GetNameHash();
+ while ((pCache = pCache->GetParent()) != NULL) {
+ if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) {
+ continue;
+ }
+ if (MatchSelector(pCache, pSel->GetNextSelector(), ePersudoType)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ case FDE_CSSSELECTORTYPE_ID:
+ dwHash = pCache->HashID();
+ if (dwHash != pSel->GetNameHash()) {
+ return FALSE;
+ }
+ break;
+ case FDE_CSSSELECTORTYPE_Class:
+ dwHash = pCache->HashClass();
+ if (dwHash != pSel->GetNameHash()) {
+ return FALSE;
+ }
+ break;
+ case FDE_CSSSELECTORTYPE_Element:
+ dwHash = pSel->GetNameHash();
+ if (dwHash != FDE_CSSUNIVERSALHASH && dwHash != pCache->HashTag()) {
+ return FALSE;
+ }
+ break;
+ case FDE_CSSSELECTORTYPE_Persudo:
+ dwHash = FDE_GetCSSPersudoByEnum(ePersudoType)->dwHash;
+ if (dwHash != pSel->GetNameHash()) {
+ return FALSE;
+ }
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ pSel = pSel->GetNextSelector();
+ }
+ return pSel == NULL && pCache != NULL;
+}
+void CFDE_CSSStyleSelector::SortRulesTo(CFDE_CSSDeclarationArray &matchDecls)
+{
+ for (FX_INT32 j = m_MatchedRules.GetUpperBound(); j >= 0; --j) {
+ FDE_LPCSSRULEDATA &pMin = m_MatchedRules.ElementAt(j);
+ FX_DWORD dwMin = pMin->dwPriority;
+ for (FX_INT32 i = j - 1; i >= 0; --i) {
+ FDE_LPCSSRULEDATA &pCur = m_MatchedRules.ElementAt(i);
+ if (dwMin > pCur->dwPriority) {
+ dwMin = pCur->dwPriority;
+ FDE_LPCSSRULEDATA p = pMin;
+ pMin = pCur;
+ pCur = p;
+ }
+ }
+ matchDecls.Add(pMin->pDeclaration);
+ }
+}
+void CFDE_CSSStyleSelector::ComputeStyle(IFDE_CSSTagProvider *pTag, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle)
+{
+ CFDE_CSSComputedStyle *pComputedStyle = (CFDE_CSSComputedStyle*)pDestStyle;
+ FXSYS_assert(pTag && iDeclCount >= 0 && pComputedStyle != NULL);
+ FX_POSITION pos = pTag->GetFirstAttribute();
+ if (pos != NULL) {
+ if (m_pInlineStyleStore == NULL) {
+ m_pInlineStyleStore = FX_CreateAllocator(FX_ALLOCTYPE_Static, 2048, 0);
+ }
+ CFDE_CSSDeclaration *pDecl = NULL;
+ CFX_WideStringC wsAttri, wsValue;
+ FX_DWORD dwAttriHash;
+ do {
+ pTag->GetNextAttribute(pos, wsAttri, wsValue);
+ dwAttriHash = FX_HashCode_String_GetW(wsAttri.GetPtr(), wsAttri.GetLength(), TRUE);
+ static const FX_DWORD s_dwStyleHash = FX_HashCode_String_GetW((FX_LPCWSTR)L"style", 5, TRUE);
+ static const FX_DWORD s_dwAlignHash = FX_HashCode_String_GetW((FX_LPCWSTR)L"align", 5, TRUE);
+ if (dwAttriHash == s_dwStyleHash) {
+ if (pDecl == NULL) {
+ pDecl = FDE_NewWith(m_pInlineStyleStore) CFDE_CSSDeclaration;
+ }
+ AppendInlineStyle(pDecl, wsValue.GetPtr(), wsValue.GetLength());
+ } else if (dwAttriHash == s_dwAlignHash) {
+ if (pDecl == NULL) {
+ pDecl = FDE_NewWith(m_pInlineStyleStore) CFDE_CSSDeclaration;
+ }
+ FDE_CSSPROPERTYARGS args;
+ args.pStringCache = NULL;
+ args.pStaticStore = m_pInlineStyleStore;
+ args.pProperty = FDE_GetCSSPropertyByEnum(FDE_CSSPROPERTY_TextAlign);
+ pDecl->AddProperty(&args, wsValue.GetPtr(), wsValue.GetLength());
+ }
+ } while (pos != NULL);
+ if (pDecl != NULL) {
+ CFDE_CSSDeclarationArray decls;
+ decls.SetSize(iDeclCount + 1);
+ IFDE_CSSDeclaration **ppInline = decls.GetData();
+ FXSYS_memcpy(ppInline, ppDeclArray, iDeclCount * sizeof(IFDE_CSSDeclaration*));
+ ppInline[iDeclCount++] = pDecl;
+ ApplyDeclarations(TRUE, (const IFDE_CSSDeclaration **)ppInline, iDeclCount, pDestStyle);
+ ApplyDeclarations(FALSE, (const IFDE_CSSDeclaration **)ppInline, iDeclCount, pDestStyle);
+ return;
+ }
+ }
+ if (iDeclCount > 0) {
+ FXSYS_assert(ppDeclArray != NULL);
+ ApplyDeclarations(TRUE, ppDeclArray, iDeclCount, pDestStyle);
+ ApplyDeclarations(FALSE, ppDeclArray, iDeclCount, pDestStyle);
+ }
+}
+void CFDE_CSSStyleSelector::ApplyDeclarations(FX_BOOL bPriority, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle)
+{
+ CFDE_CSSComputedStyle *pComputedStyle = (CFDE_CSSComputedStyle*)pDestStyle;
+ IFDE_CSSValue *pVal;
+ FX_BOOL bImportant;
+ FX_INT32 i;
+ if (bPriority) {
+ IFDE_CSSValue *pLastest = NULL, *pImportant = NULL;
+ for (i = 0; i < iDeclCount; ++i) {
+ pVal = ppDeclArray[i]->GetProperty(FDE_CSSPROPERTY_FontSize, bImportant);
+ if (pVal == NULL) {
+ continue;
+ } else if (bImportant) {
+ pImportant = pVal;
+ } else {
+ pLastest = pVal;
+ }
+ }
+ if (pImportant) {
+ ApplyProperty(FDE_CSSPROPERTY_FontSize, pImportant, pComputedStyle);
+ } else if (pLastest) {
+ ApplyProperty(FDE_CSSPROPERTY_FontSize, pLastest, pComputedStyle);
+ }
+ } else {
+ CFDE_CSSDeclarationArray importants;
+ const IFDE_CSSDeclaration *pDecl = NULL;
+ FDE_CSSPROPERTY eProp;
+ FX_POSITION pos;
+ for (i = 0; i < iDeclCount; ++i) {
+ pDecl = ppDeclArray[i];
+ pos = pDecl->GetStartPosition();
+ while (pos != NULL) {
+ pDecl->GetNextProperty(pos, eProp, pVal, bImportant);
+ if (eProp == FDE_CSSPROPERTY_FontSize) {
+ continue;
+ } else if (!bImportant) {
+ ApplyProperty(eProp, pVal, pComputedStyle);
+ } else if (importants.GetSize() == 0 || importants[importants.GetUpperBound()] != pDecl) {
+ importants.Add((IFDE_CSSDeclaration*)pDecl);
+ }
+ }
+ }
+ iDeclCount = importants.GetSize();
+ for (i = 0; i < iDeclCount; ++i) {
+ pDecl = importants[i];
+ pos = pDecl->GetStartPosition();
+ while (pos != NULL) {
+ pDecl->GetNextProperty(pos, eProp, pVal, bImportant);
+ if (bImportant && eProp != FDE_CSSPROPERTY_FontSize) {
+ ApplyProperty(eProp, pVal, pComputedStyle);
+ }
+ }
+ }
+ CFX_WideString wsName, wsValue;
+ pos = pDecl->GetStartCustom();
+ while (pos) {
+ pDecl->GetNextCustom(pos, wsName, wsValue);
+ pComputedStyle->AddCustomStyle(wsName, wsValue);
+ }
+ }
+}
+void CFDE_CSSStyleSelector::AppendInlineStyle(CFDE_CSSDeclaration *pDecl, FX_LPCWSTR psz, FX_INT32 iLen)
+{
+ FXSYS_assert(pDecl != NULL && psz != NULL && iLen > 0);
+ IFDE_CSSSyntaxParser *pSyntax = IFDE_CSSSyntaxParser::Create();
+ if (pSyntax == NULL) {
+ return;
+ }
+ if (pSyntax->Init(psz, iLen, 32, TRUE)) {
+ FX_INT32 iLen;
+ FX_LPCWSTR psz;
+ FDE_CSSPROPERTYARGS args;
+ args.pStringCache = NULL;
+ args.pStaticStore = m_pInlineStyleStore;
+ args.pProperty = NULL;
+ CFX_WideString wsName;
+ for (;;) {
+ FDE_CSSSYNTAXSTATUS eStatus = pSyntax->DoSyntaxParse();
+ if (eStatus == FDE_CSSSYNTAXSTATUS_PropertyName) {
+ psz = pSyntax->GetCurrentString(iLen);
+ args.pProperty = FDE_GetCSSPropertyByName(psz, iLen);
+ if (args.pProperty == NULL) {
+ wsName = CFX_WideStringC(psz, iLen);
+ }
+ } else if (eStatus == FDE_CSSSYNTAXSTATUS_PropertyValue) {
+ if (args.pProperty != NULL) {
+ psz = pSyntax->GetCurrentString(iLen);
+ if (iLen > 0) {
+ pDecl->AddProperty(&args, psz, iLen);
+ }
+ } else if (iLen > 0) {
+ psz = pSyntax->GetCurrentString(iLen);
+ if (iLen > 0) {
+ pDecl->AddProperty(&args, wsName, wsName.GetLength(), psz, iLen);
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ pSyntax->Release();
+}
+void CFDE_CSSStyleSelector::ApplyProperty(FDE_CSSPROPERTY eProperty, IFDE_CSSValue *pValue, CFDE_CSSComputedStyle *pComputedStyle)
+{
+#define FDE_CSSNONINHERITS (pComputedStyle->m_NonInheritedData)
+#define FDE_CSSINHERITS (pComputedStyle->m_InheritedData)
+#define FDE_CSSFONTSIZE (FDE_CSSINHERITS.m_fFontSize)
+ if (pComputedStyle->m_InheritedData.m_pFontFamily && *(FX_DWORD*)pComputedStyle->m_InheritedData.m_pFontFamily == 0xcdcdcdcd) {
+ pComputedStyle = pComputedStyle;
+ }
+ if (pValue->GetType() == FDE_CSSVALUETYPE_Primitive) {
+ IFDE_CSSPrimitiveValue *pPrimitive = (IFDE_CSSPrimitiveValue*)pValue;
+ FDE_CSSPRIMITIVETYPE eType = pPrimitive->GetPrimitiveType();
+ switch (eProperty) {
+ case FDE_CSSPROPERTY_Display:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eDisplay = ToDisplay(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_FontSize: {
+ FX_FLOAT &fFontSize = FDE_CSSFONTSIZE;
+ if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ fFontSize = ApplyNumber(eType, pPrimitive->GetFloat(), fFontSize);
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ fFontSize = ToFontSize(pPrimitive->GetEnum(), fFontSize);
+ }
+ }
+ break;
+ case FDE_CSSPROPERTY_LineHeight:
+ if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FDE_CSSINHERITS.m_fLineHeight = pPrimitive->GetFloat() * FDE_CSSFONTSIZE;
+ } else if (eType > FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ FDE_CSSINHERITS.m_fLineHeight = ApplyNumber(eType, pPrimitive->GetFloat(), FDE_CSSFONTSIZE);
+ }
+ break;
+ case FDE_CSSPROPERTY_TextAlign:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eTextAligh = ToTextAlign(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_TextIndent:
+ SetLengthWithPercent(FDE_CSSINHERITS.m_TextIndent, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_FontWeight:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_wFontWeight = ToFontWeight(pPrimitive->GetEnum());
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FX_INT32 iValue = (FX_INT32)pPrimitive->GetFloat() / 100;
+ if (iValue >= 1 && iValue <= 9) {
+ FDE_CSSINHERITS.m_wFontWeight = iValue * 100;
+ }
+ }
+ break;
+ case FDE_CSSPROPERTY_FontStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eFontStyle = ToFontStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Color:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSINHERITS.m_dwFontColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_MarginLeft:
+ FDE_CSSNONINHERITS.m_bHasMargin |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.left, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MarginTop:
+ FDE_CSSNONINHERITS.m_bHasMargin |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.top, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MarginRight:
+ FDE_CSSNONINHERITS.m_bHasMargin |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.right, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MarginBottom:
+ FDE_CSSNONINHERITS.m_bHasMargin |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_MarginWidth.bottom, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_PaddingLeft:
+ FDE_CSSNONINHERITS.m_bHasPadding |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.left, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_PaddingTop:
+ FDE_CSSNONINHERITS.m_bHasPadding |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.top, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_PaddingRight:
+ FDE_CSSNONINHERITS.m_bHasPadding |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.right, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_PaddingBottom:
+ FDE_CSSNONINHERITS.m_bHasPadding |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_PaddingWidth.bottom, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderLeftWidth:
+ FDE_CSSNONINHERITS.m_bHasBorder |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.left, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderTopWidth:
+ FDE_CSSNONINHERITS.m_bHasBorder |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.top, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderRightWidth:
+ FDE_CSSNONINHERITS.m_bHasBorder |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.right, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderBottomWidth:
+ FDE_CSSNONINHERITS.m_bHasBorder |= SetLengthWithPercent(FDE_CSSNONINHERITS.m_BorderWidth.bottom, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BorderLeftStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBDRLeftStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderTopStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBDRTopStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderRightStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBDRRightStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderBottomStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBDRBottomStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderLeftColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBDRLeftColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderTopColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBDRTopColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderRightColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBDRRightColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_BorderBottomColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBDRBottomColor = pPrimitive->GetRGBColor();
+ }
+ break;
+ case FDE_CSSPROPERTY_ListStyleType:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eListStyleType = ToListStyleType(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_ListStylePosition:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eListStylePosition = ToListStylePosition(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BackgroundColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwBKGColor = pPrimitive->GetRGBColor();
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_dwBKGColor = 0;
+ }
+ break;
+ case FDE_CSSPROPERTY_Visibility:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eVisibility = ToVisibility(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Width:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_BoxSize.cx, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_Height:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_BoxSize.cy, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MinWidth:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_MinBoxSize.cx, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MinHeight:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_MinBoxSize.cy, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MaxWidth:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_MaxBoxSize.cx, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_MaxHeight:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_MaxBoxSize.cy, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_VerticalAlign:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eVerticalAlign = ToVerticalAlign(pPrimitive->GetEnum());
+ } else if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ FDE_CSSNONINHERITS.m_eVerticalAlign = FDE_CSSVERTICALALIGN_Number;
+ FDE_CSSNONINHERITS.m_fVerticalAlign = ApplyNumber(eType, pPrimitive->GetFloat(), FDE_CSSFONTSIZE);
+ }
+ break;
+ case FDE_CSSPROPERTY_WhiteSpace:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eWhiteSpace = ToWhiteSpace(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_TextTransform:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eTextTransform = ToTextTransform(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_FontVariant:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eFontVariant = ToFontVariant(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_LetterSpacing:
+ if (eType == FDE_CSSPRIMITIVETYPE_Percent) {
+ break;
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_LetterSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
+ } else if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ SetLengthWithPercent(FDE_CSSINHERITS.m_LetterSpacing, eType, pPrimitive, FDE_CSSFONTSIZE);
+ }
+ break;
+ case FDE_CSSPROPERTY_WordSpacing:
+ if (eType == FDE_CSSPRIMITIVETYPE_Percent) {
+ break;
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_WordSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
+ } else if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ SetLengthWithPercent(FDE_CSSINHERITS.m_WordSpacing, eType, pPrimitive, FDE_CSSFONTSIZE);
+ }
+ break;
+ case FDE_CSSPROPERTY_Float:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eFloat = ToFloat(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Clear:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eClear = ToClear(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_WritingMode:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eWritingMode = ToWritingMode(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_WordBreak:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eWordBreak = ToWordBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Widows:
+ if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FDE_CSSINHERITS.m_iWidows = (FX_INT32)pPrimitive->GetFloat();
+ }
+ break;
+ case FDE_CSSPROPERTY_Orphans:
+ if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FDE_CSSINHERITS.m_iOrphans = (FX_INT32)pPrimitive->GetFloat();
+ }
+ break;
+ case FDE_CSSPROPERTY_TextEmphasisColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ switch (pPrimitive->GetEnum()) {
+ case FDE_CSSPROPERTYVALUE_Transparent:
+ FDE_CSSINHERITS.m_dwTextEmphasisColor = 0;
+ FDE_CSSINHERITS.m_bTextEmphasisColorCurrent = FALSE;
+ break;
+ case FDE_CSSPROPERTYVALUE_Currentcolor:
+ FDE_CSSINHERITS.m_bTextEmphasisColorCurrent = TRUE;
+ break;
+ default:
+ break;
+ }
+ } else if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSINHERITS.m_dwTextEmphasisColor = pPrimitive->GetRGBColor();
+ FDE_CSSINHERITS.m_bTextEmphasisColorCurrent = FALSE;
+ }
+ break;
+ case FDE_CSSPROPERTY_PageBreakBefore:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ePageBreakBefore = ToPageBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_PageBreakAfter:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ePageBreakAfter = ToPageBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_PageBreakInside:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ePageBreakInside = ToPageBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_OverflowX:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eOverflowX = ToOverflow(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_OverflowY:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eOverflowY = ToOverflow(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_LineBreak:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eLineBreak = ToLineBreak(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_ColumnCount:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ColumnCount.Set(FDE_CSSLENGTHUNIT_Auto);
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Number) {
+ FDE_CSSNONINHERITS.m_ColumnCount.Set(FDE_CSSLENGTHUNIT_Point, pPrimitive->GetFloat());
+ }
+ break;
+ case FDE_CSSPROPERTY_ColumnGap:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_ColumnGap, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_ColumnRuleColor:
+ if (eType == FDE_CSSPRIMITIVETYPE_RGB) {
+ FDE_CSSNONINHERITS.m_dwColumnRuleColor = pPrimitive->GetRGBColor();
+ FDE_CSSNONINHERITS.m_bColumnRuleColorSame = FALSE;
+ }
+ break;
+ case FDE_CSSPROPERTY_ColumnRuleStyle:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eColumnRuleStyle = ToBorderStyle(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_ColumnRuleWidth:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_ColumnRuleWidth, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_ColumnWidth:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_ColumnWidth, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_BackgroundImage:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_pszBKGImage = NULL;
+ } else if (eType == FDE_CSSPRIMITIVETYPE_URI) {
+ FX_INT32 iLength;
+ FDE_CSSNONINHERITS.m_pszBKGImage = pPrimitive->GetString(iLength);
+ }
+ break;
+ case FDE_CSSPROPERTY_Position:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_ePosition = ToPosition(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_Top:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_Top, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_Bottom:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_Bottom, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_Left:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_Left, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_Right:
+ SetLengthWithPercent(FDE_CSSNONINHERITS.m_Right, eType, pPrimitive, FDE_CSSFONTSIZE);
+ break;
+ case FDE_CSSPROPERTY_ListStyleImage:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_pszListStyleImage = NULL;
+ } else if (eType == FDE_CSSPRIMITIVETYPE_URI) {
+ FX_INT32 iLength;
+ FDE_CSSINHERITS.m_pszListStyleImage = pPrimitive->GetString(iLength);
+ }
+ break;
+ case FDE_CSSPROPERTY_CaptionSide:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eCaptionSide = ToCaptionSide(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BackgroundRepeat:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBKGRepeat = ToBKGRepeat(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_BackgroundAttachment:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSNONINHERITS.m_eBKGAttachment = ToBKGAttachment(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_RubyAlign:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eRubyAlign = ToRubyAlign(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_RubyOverhang:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eRubyOverhang = ToRubyOverhang(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_RubyPosition:
+ if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ FDE_CSSINHERITS.m_eRubyPosition = ToRubyPosition(pPrimitive->GetEnum());
+ }
+ break;
+ case FDE_CSSPROPERTY_RubySpan:
+ FDE_CSSNONINHERITS.m_pRubySpan = pPrimitive;
+ break;
+ default:
+ break;
+ }
+ } else if (pValue->GetType() == FDE_CSSVALUETYPE_List) {
+ IFDE_CSSValueList *pList = (IFDE_CSSValueList*)pValue;
+ FX_INT32 iCount = pList->CountValues();
+ if (iCount > 0) {
+ switch (eProperty) {
+ case FDE_CSSPROPERTY_FontFamily:
+ FDE_CSSINHERITS.m_pFontFamily = pList;
+ break;
+ case FDE_CSSPROPERTY_TextDecoration:
+ FDE_CSSNONINHERITS.m_dwTextDecoration = ToTextDecoration(pList);
+ break;
+ case FDE_CSSPROPERTY_CounterIncrement: {
+ if (FDE_CSSNONINHERITS.m_pCounterStyle == NULL) {
+ FDE_CSSNONINHERITS.m_pCounterStyle = FDE_New CFDE_CSSCounterStyle;
+ }
+ FDE_CSSNONINHERITS.m_pCounterStyle->SetCounterIncrementList(pList);
+ }
+ break;
+ case FDE_CSSPROPERTY_CounterReset: {
+ if (FDE_CSSNONINHERITS.m_pCounterStyle == NULL) {
+ FDE_CSSNONINHERITS.m_pCounterStyle = FDE_New CFDE_CSSCounterStyle;
+ }
+ FDE_CSSNONINHERITS.m_pCounterStyle->SetCounterResetList(pList);
+ }
+ break;
+ case FDE_CSSPROPERTY_Content:
+ FDE_CSSNONINHERITS.m_pContentList = pList;
+ break;
+ case FDE_CSSPROPERTY_Quotes:
+ FDE_CSSINHERITS.m_pQuotes = pList;
+ break;
+ case FDE_CSSPROPERTY_TextCombine: {
+ for (FX_INT32 i = 0; i < pList->CountValues(); i++) {
+ IFDE_CSSPrimitiveValue *pVal = (IFDE_CSSPrimitiveValue*)pList->GetValue(i);
+ switch (pVal->GetPrimitiveType()) {
+ case FDE_CSSPRIMITIVETYPE_Enum: {
+ switch (pVal->GetEnum()) {
+ case FDE_CSSPROPERTYVALUE_None: {
+ FDE_CSSNONINHERITS.m_eTextCombine = FDE_CSSTEXTCOMBINE_None;
+ FDE_CSSNONINHERITS.m_bHasTextCombineNumber = FALSE;
+ }
+ break;
+ case FDE_CSSPROPERTYVALUE_Horizontal: {
+ FDE_CSSNONINHERITS.m_eTextCombine = FDE_CSSTEXTCOMBINE_Horizontal;
+ FDE_CSSNONINHERITS.m_bHasTextCombineNumber = FALSE;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_Number:
+ FDE_CSSNONINHERITS.m_fTextCombineNumber = pVal->GetFloat();
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ case FDE_CSSPROPERTY_TextEmphasisStyle: {
+ FDE_CSSTEXTEMPHASISFILL eFill;
+ FDE_CSSTEXTEMPHASISMARK eMark;
+ for (FX_INT32 i = 0; i < pList->CountValues(); i++) {
+ IFDE_CSSPrimitiveValue *pVal = (IFDE_CSSPrimitiveValue*)pList->GetValue(i);
+ switch (pVal->GetPrimitiveType()) {
+ case FDE_CSSPRIMITIVETYPE_Enum: {
+ if (ToTextEmphasisFill(pVal->GetEnum(), eFill)) {
+ FDE_CSSINHERITS.m_eTextEmphasisFill = eFill;
+ continue;
+ } else if (ToTextEmphasisMark(pVal->GetEnum(), eMark)) {
+ FDE_CSSINHERITS.m_eTextEmphasisMark = eMark;
+ }
+ }
+ break;
+ case FDE_CSSPRIMITIVETYPE_String: {
+ FDE_CSSINHERITS.m_eTextEmphasisMark = FDE_CSSTEXTEMPHASISMARK_Custom;
+ FX_INT32 iLen;
+ FDE_CSSINHERITS.m_pszTextEmphasisCustomMark = pVal->GetString(iLen);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ FXSYS_assert(FALSE);
+ }
+}
+FX_FLOAT CFDE_CSSStyleSelector::ApplyNumber(FDE_CSSPRIMITIVETYPE eUnit, FX_FLOAT fValue, FX_FLOAT fPercentBase)
+{
+ switch (eUnit) {
+ case FDE_CSSPRIMITIVETYPE_PX:
+ case FDE_CSSPRIMITIVETYPE_Number:
+ return fValue * 72 / 96;
+ case FDE_CSSPRIMITIVETYPE_PT:
+ return fValue;
+ case FDE_CSSPRIMITIVETYPE_EMS:
+ case FDE_CSSPRIMITIVETYPE_EXS:
+ return fValue * fPercentBase;
+ case FDE_CSSPRIMITIVETYPE_Percent:
+ return fValue * fPercentBase / 100.0f;
+ case FDE_CSSPRIMITIVETYPE_CM:
+ return fValue * 28.3464f;
+ case FDE_CSSPRIMITIVETYPE_MM:
+ return fValue * 2.8346f;
+ case FDE_CSSPRIMITIVETYPE_IN:
+ return fValue * 72.0f;
+ case FDE_CSSPRIMITIVETYPE_PC:
+ return fValue / 12.0f;
+ default:
+ return fValue;
+ }
+}
+FDE_CSSRUBYSPAN CFDE_CSSStyleSelector::ToRubySpan(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ default:
+ return FDE_CSSRUBYSPAN_None;
+ }
+}
+FDE_CSSRUBYPOSITION CFDE_CSSStyleSelector::ToRubyPosition(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Before:
+ return FDE_CSSRUBYPOSITION_Before;
+ case FDE_CSSPROPERTYVALUE_After:
+ return FDE_CSSRUBYPOSITION_After;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSRUBYPOSITION_Right;
+ case FDE_CSSPROPERTYVALUE_Inline:
+ return FDE_CSSRUBYPOSITION_Inline;
+ default:
+ return FDE_CSSRUBYPOSITION_Before;
+ }
+}
+FDE_CSSRUBYOVERHANG CFDE_CSSStyleSelector::ToRubyOverhang(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSRUBYOVERHANG_Auto;
+ case FDE_CSSPROPERTYVALUE_Start:
+ return FDE_CSSRUBYOVERHANG_Start;
+ case FDE_CSSPROPERTYVALUE_End:
+ return FDE_CSSRUBYOVERHANG_End;
+ case FDE_CSSPROPERTYVALUE_None:
+ default:
+ return FDE_CSSRUBYOVERHANG_None;
+ }
+}
+FDE_CSSRUBYALIGN CFDE_CSSStyleSelector::ToRubyAlign(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSRUBYALIGN_Auto;
+ case FDE_CSSPROPERTYVALUE_Start:
+ return FDE_CSSRUBYALIGN_Start;
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSRUBYALIGN_End;
+ case FDE_CSSPROPERTYVALUE_Center:
+ return FDE_CSSRUBYALIGN_Center;
+ case FDE_CSSPROPERTYVALUE_End:
+ return FDE_CSSRUBYALIGN_End;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSRUBYALIGN_Right;
+ case FDE_CSSPROPERTYVALUE_DistributeLetter:
+ return FDE_CSSRUBYALIGN_DistributeLetter;
+ case FDE_CSSPROPERTYVALUE_DistributeSpace:
+ return FDE_CSSRUBYALIGN_DistributeSpace;
+ case FDE_CSSPROPERTYVALUE_LineEdge:
+ return FDE_CSSRUBYALIGN_LineEdge;
+ default:
+ return FDE_CSSRUBYALIGN_Auto;
+ }
+}
+FX_BOOL CFDE_CSSStyleSelector::ToTextEmphasisMark(FDE_CSSPROPERTYVALUE eValue, FDE_CSSTEXTEMPHASISMARK &eMark)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ eMark = FDE_CSSTEXTEMPHASISMARK_None;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Dot:
+ eMark = FDE_CSSTEXTEMPHASISMARK_Dot;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Circle:
+ eMark = FDE_CSSTEXTEMPHASISMARK_Circle;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_DoubleCircle:
+ eMark = FDE_CSSTEXTEMPHASISMARK_DoubleCircle;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Triangle:
+ eMark = FDE_CSSTEXTEMPHASISMARK_Triangle;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Sesame:
+ eMark = FDE_CSSTEXTEMPHASISMARK_Sesame;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFDE_CSSStyleSelector::ToTextEmphasisFill(FDE_CSSPROPERTYVALUE eValue, FDE_CSSTEXTEMPHASISFILL &eFill)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Filled:
+ eFill = FDE_CSSTEXTEMPHASISFILL_Filled;
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Open:
+ eFill = FDE_CSSTEXTEMPHASISFILL_Open;
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+FDE_CSSBKGATTACHMENT CFDE_CSSStyleSelector::ToBKGAttachment(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Fixed:
+ return FDE_CSSBKGATTACHMENT_Fixed;
+ case FDE_CSSPROPERTYVALUE_Scroll:
+ return FDE_CSSBKGATTACHMENT_Scroll;
+ default:
+ return FDE_CSSBKGATTACHMENT_Fixed;
+ }
+}
+FDE_CSSCAPTIONSIDE CFDE_CSSStyleSelector::ToCaptionSide(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Top:
+ return FDE_CSSCAPTIONSIDE_Top;
+ case FDE_CSSPROPERTYVALUE_Bottom:
+ return FDE_CSSCAPTIONSIDE_Bottom;
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSCAPTIONSIDE_Left;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSCAPTIONSIDE_Right;
+ case FDE_CSSPROPERTYVALUE_Before:
+ return FDE_CSSCAPTIONSIDE_Before;
+ case FDE_CSSPROPERTYVALUE_After:
+ return FDE_CSSCAPTIONSIDE_After;
+ default:
+ return FDE_CSSCAPTIONSIDE_Top;
+ }
+}
+FDE_CSSPOSITION CFDE_CSSStyleSelector::ToPosition(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Static:
+ return FDE_CSSPOSITION_Static;
+ case FDE_CSSPROPERTYVALUE_Relative:
+ return FDE_CSSPOSITION_Relative;
+ case FDE_CSSPROPERTYVALUE_Fixed:
+ return FDE_CSSPOSITION_Fixed;
+ case FDE_CSSPROPERTYVALUE_Absolute:
+ return FDE_CSSPOSITION_Absolute;
+ default:
+ return FDE_CSSPOSITION_Static;
+ }
+}
+FDE_CSSCURSOR CFDE_CSSStyleSelector::ToCursor(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSCURSOR_Auto;
+ case FDE_CSSPROPERTYVALUE_Crosshair:
+ return FDE_CSSCURSOR_Crosshair;
+ case FDE_CSSPROPERTYVALUE_Default:
+ return FDE_CSSCURSOR_Default;
+ case FDE_CSSPROPERTYVALUE_Pointer:
+ return FDE_CSSCURSOR_Pointer;
+ case FDE_CSSPROPERTYVALUE_Move:
+ return FDE_CSSCURSOR_Move;
+ case FDE_CSSPROPERTYVALUE_EResize:
+ return FDE_CSSCURSOR_EResize;
+ case FDE_CSSPROPERTYVALUE_NeResize:
+ return FDE_CSSCURSOR_NeResize;
+ case FDE_CSSPROPERTYVALUE_NwResize:
+ return FDE_CSSCURSOR_NwResize;
+ case FDE_CSSPROPERTYVALUE_NResize:
+ return FDE_CSSCURSOR_NResize;
+ case FDE_CSSPROPERTYVALUE_SeResize:
+ return FDE_CSSCURSOR_SeResize;
+ case FDE_CSSPROPERTYVALUE_SwResize:
+ return FDE_CSSCURSOR_SwResize;
+ default:
+ return FDE_CSSCURSOR_Auto;
+ }
+}
+FDE_CSSBKGREPEAT CFDE_CSSStyleSelector::ToBKGRepeat(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Repeat:
+ return FDE_CSSBKGREPEAT_Repeat;
+ case FDE_CSSPROPERTYVALUE_RepeatX:
+ return FDE_CSSBKGREPEAT_RepeatX;
+ case FDE_CSSPROPERTYVALUE_RepeatY:
+ return FDE_CSSBKGREPEAT_RepeatY;
+ case FDE_CSSPROPERTYVALUE_NoRepeat:
+ return FDE_CSSBKGREPEAT_NoRepeat;
+ default:
+ return FDE_CSSBKGREPEAT_Repeat;
+ }
+}
+FDE_CSSTEXTCOMBINE CFDE_CSSStyleSelector::ToTextCombine(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Horizontal:
+ return FDE_CSSTEXTCOMBINE_Horizontal;
+ case FDE_CSSPROPERTYVALUE_None:
+ default:
+ return FDE_CSSTEXTCOMBINE_None;
+ }
+}
+FDE_CSSLINEBREAK CFDE_CSSStyleSelector::ToLineBreak(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSLINEBREAK_Auto;
+ case FDE_CSSPROPERTYVALUE_Loose:
+ return FDE_CSSLINEBREAK_Loose;
+ case FDE_CSSPROPERTYVALUE_Normal:
+ return FDE_CSSLINEBREAK_Normal;
+ case FDE_CSSPROPERTYVALUE_Strict:
+ return FDE_CSSLINEBREAK_Strict;
+ default:
+ return FDE_CSSLINEBREAK_Auto;
+ }
+}
+FDE_CSSOVERFLOW CFDE_CSSStyleSelector::ToOverflow(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Visible:
+ return FDE_CSSOVERFLOW_Visible;
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ return FDE_CSSOVERFLOW_Hidden;
+ case FDE_CSSPROPERTYVALUE_Scroll:
+ return FDE_CSSOVERFLOW_Scroll;
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSOVERFLOW_Auto;
+ case FDE_CSSPROPERTYVALUE_NoDisplay:
+ return FDE_CSSOVERFLOW_NoDisplay;
+ case FDE_CSSPROPERTYVALUE_NoContent:
+ return FDE_CSSOVERFLOW_NoContent;
+ default:
+ return FDE_CSSOVERFLOW_Visible;
+ }
+}
+FDE_CSSWRITINGMODE CFDE_CSSStyleSelector::ToWritingMode(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_HorizontalTb:
+ return FDE_CSSWRITINGMODE_HorizontalTb;
+ case FDE_CSSPROPERTYVALUE_VerticalRl:
+ return FDE_CSSWRITINGMODE_VerticalRl;
+ case FDE_CSSPROPERTYVALUE_VerticalLr:
+ return FDE_CSSWRITINGMODE_VerticalLr;
+ default:
+ return FDE_CSSWRITINGMODE_HorizontalTb;
+ }
+}
+FDE_CSSWORDBREAK CFDE_CSSStyleSelector::ToWordBreak(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Normal:
+ return FDE_CSSWORDBREAK_Normal;
+ case FDE_CSSPROPERTYVALUE_KeepAll:
+ return FDE_CSSWORDBREAK_KeepAll;
+ case FDE_CSSPROPERTYVALUE_BreakAll:
+ return FDE_CSSWORDBREAK_BreakAll;
+ case FDE_CSSPROPERTYVALUE_KeepWords:
+ return FDE_CSSWORDBREAK_KeepWords;
+ default:
+ return FDE_CSSWORDBREAK_Normal;
+ }
+}
+FDE_CSSFLOAT CFDE_CSSStyleSelector::ToFloat(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSFLOAT_Left;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSFLOAT_Right;
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSFLOAT_None;
+ default:
+ return FDE_CSSFLOAT_None;
+ }
+}
+FDE_CSSCLEAR CFDE_CSSStyleSelector::ToClear(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSCLEAR_None;
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSCLEAR_Left;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSCLEAR_Right;
+ case FDE_CSSPROPERTYVALUE_Both:
+ return FDE_CSSCLEAR_Both;
+ default:
+ return FDE_CSSCLEAR_None;
+ }
+}
+FDE_CSSPAGEBREAK CFDE_CSSStyleSelector::ToPageBreak(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Avoid:
+ return FDE_CSSPAGEBREAK_Avoid;
+ case FDE_CSSPROPERTYVALUE_Auto:
+ return FDE_CSSPAGEBREAK_Auto;
+ case FDE_CSSPROPERTYVALUE_Always:
+ return FDE_CSSPAGEBREAK_Always;
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSPAGEBREAK_Left;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSPAGEBREAK_Right;
+ default:
+ return FDE_CSSPAGEBREAK_Auto;
+ }
+}
+FDE_CSSDISPLAY CFDE_CSSStyleSelector::ToDisplay(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Inline:
+ return FDE_CSSDISPLAY_Inline;
+ case FDE_CSSPROPERTYVALUE_Block:
+ return FDE_CSSDISPLAY_Block;
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSDISPLAY_None;
+ case FDE_CSSPROPERTYVALUE_ListItem:
+ return FDE_CSSDISPLAY_ListItem;
+ case FDE_CSSPROPERTYVALUE_TableCell:
+ return FDE_CSSDISPLAY_TableCell;
+ case FDE_CSSPROPERTYVALUE_TableRow:
+ return FDE_CSSDISPLAY_TableRow;
+ case FDE_CSSPROPERTYVALUE_Table:
+ return FDE_CSSDISPLAY_Table;
+ case FDE_CSSPROPERTYVALUE_TableCaption:
+ return FDE_CSSDISPLAY_TableCaption;
+ case FDE_CSSPROPERTYVALUE_TableRowGroup:
+ return FDE_CSSDISPLAY_TableRowGroup;
+ case FDE_CSSPROPERTYVALUE_TableHeaderGroup:
+ return FDE_CSSDISPLAY_TableHeaderGroup;
+ case FDE_CSSPROPERTYVALUE_TableFooterGroup:
+ return FDE_CSSDISPLAY_TableFooterGroup;
+ case FDE_CSSPROPERTYVALUE_TableColumnGroup:
+ return FDE_CSSDISPLAY_TableColumnGroup;
+ case FDE_CSSPROPERTYVALUE_TableColumn:
+ return FDE_CSSDISPLAY_TableColumn;
+ case FDE_CSSPROPERTYVALUE_InlineTable:
+ return FDE_CSSDISPLAY_InlineTable;
+ case FDE_CSSPROPERTYVALUE_InlineBlock:
+ return FDE_CSSDISPLAY_InlineBlock;
+ case FDE_CSSPROPERTYVALUE_RunIn:
+ return FDE_CSSDISPLAY_RunIn;
+ case FDE_CSSPROPERTYVALUE_Ruby:
+ return FDE_CSSDISPLAY_Ruby;
+ case FDE_CSSPROPERTYVALUE_RubyBase:
+ return FDE_CSSDISPLAY_RubyBase;
+ case FDE_CSSPROPERTYVALUE_RubyText:
+ return FDE_CSSDISPLAY_RubyText;
+ case FDE_CSSPROPERTYVALUE_RubyBaseGroup:
+ return FDE_CSSDISPLSY_RubyBaseGroup;
+ case FDE_CSSPROPERTYVALUE_RubyTextGroup:
+ return FDE_CSSDISPLAY_RubyTextGroup;
+ default:
+ return FDE_CSSDISPLAY_Inline;
+ }
+}
+FDE_CSSTEXTALIGN CFDE_CSSStyleSelector::ToTextAlign(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Left:
+ return FDE_CSSTEXTALIGN_Left;
+ case FDE_CSSPROPERTYVALUE_Center:
+ return FDE_CSSTEXTALIGN_Center;
+ case FDE_CSSPROPERTYVALUE_Right:
+ return FDE_CSSTEXTALIGN_Right;
+ case FDE_CSSPROPERTYVALUE_Justify:
+ return FDE_CSSTEXTALIGN_Justify;
+ default:
+ return FDE_CSSTEXTALIGN_Left;
+ }
+}
+FX_WORD CFDE_CSSStyleSelector::ToFontWeight(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Normal:
+ return 400;
+ case FDE_CSSPROPERTYVALUE_Bold:
+ return 700;
+ case FDE_CSSPROPERTYVALUE_Bolder:
+ return 900;
+ case FDE_CSSPROPERTYVALUE_Lighter:
+ return 200;
+ default:
+ return 400;
+ }
+}
+FDE_CSSFONTSTYLE CFDE_CSSStyleSelector::ToFontStyle(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Italic:
+ case FDE_CSSPROPERTYVALUE_Oblique:
+ return FDE_CSSFONTSTYLE_Italic;
+ default:
+ return FDE_CSSFONTSTYLE_Normal;
+ }
+}
+FDE_CSSBORDERSTYLE CFDE_CSSStyleSelector::ToBorderStyle(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSBORDERSTYLE_None;
+ case FDE_CSSPROPERTYVALUE_Solid:
+ return FDE_CSSBORDERSTYLE_Solid;
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ return FDE_CSSBORDERSTYLE_Hidden;
+ case FDE_CSSPROPERTYVALUE_Dotted:
+ return FDE_CSSBORDERSTYLE_Dotted;
+ case FDE_CSSPROPERTYVALUE_Dashed:
+ return FDE_CSSBORDERSTYLE_Dashed;
+ case FDE_CSSPROPERTYVALUE_Double:
+ return FDE_CSSBORDERSTYLE_Double;
+ case FDE_CSSPROPERTYVALUE_Groove:
+ return FDE_CSSBORDERSTYLE_Groove;
+ case FDE_CSSPROPERTYVALUE_Ridge:
+ return FDE_CSSBORDERSTYLE_Ridge;
+ case FDE_CSSPROPERTYVALUE_Inset:
+ return FDE_CSSBORDERSTYLE_Inset;
+ case FDE_CSSPROPERTYVALUE_Outset:
+ return FDE_CSSBORDERSTYLE_outset;
+ default:
+ return FDE_CSSBORDERSTYLE_None;
+ }
+}
+FX_BOOL CFDE_CSSStyleSelector::SetLengthWithPercent(FDE_CSSLENGTH &width, FDE_CSSPRIMITIVETYPE eType, IFDE_CSSPrimitiveValue *pPrimitive, FX_FLOAT fFontSize)
+{
+ if (eType == FDE_CSSPRIMITIVETYPE_Percent) {
+ width.Set(FDE_CSSLENGTHUNIT_Percent, pPrimitive->GetFloat() / 100.0f);
+ return width.NonZero();
+ } else if (eType >= FDE_CSSPRIMITIVETYPE_Number && eType <= FDE_CSSPRIMITIVETYPE_PC) {
+ FX_FLOAT fValue = ApplyNumber(eType, pPrimitive->GetFloat(), fFontSize);
+ width.Set(FDE_CSSLENGTHUNIT_Point, fValue);
+ return width.NonZero();
+ } else if (eType == FDE_CSSPRIMITIVETYPE_Enum) {
+ switch (pPrimitive->GetEnum()) {
+ case FDE_CSSPROPERTYVALUE_Auto:
+ width.Set(FDE_CSSLENGTHUNIT_Auto);
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_None:
+ width.Set(FDE_CSSLENGTHUNIT_None);
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Thin:
+ width.Set(FDE_CSSLENGTHUNIT_Point, 2);
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Medium:
+ width.Set(FDE_CSSLENGTHUNIT_Point, 3);
+ return TRUE;
+ case FDE_CSSPROPERTYVALUE_Thick:
+ width.Set(FDE_CSSLENGTHUNIT_Point, 4);
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ }
+ return FALSE;
+}
+FX_FLOAT CFDE_CSSStyleSelector::ToFontSize(FDE_CSSPROPERTYVALUE eValue, FX_FLOAT fCurFontSize)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_XxSmall:
+ return m_fDefFontSize / 1.2f / 1.2f / 1.2f;
+ case FDE_CSSPROPERTYVALUE_XSmall:
+ return m_fDefFontSize / 1.2f / 1.2f;
+ case FDE_CSSPROPERTYVALUE_Small:
+ return m_fDefFontSize / 1.2f;
+ case FDE_CSSPROPERTYVALUE_Medium:
+ return m_fDefFontSize;
+ case FDE_CSSPROPERTYVALUE_Large:
+ return m_fDefFontSize * 1.2f;
+ case FDE_CSSPROPERTYVALUE_XLarge:
+ return m_fDefFontSize * 1.2f * 1.2f;
+ case FDE_CSSPROPERTYVALUE_XxLarge:
+ return m_fDefFontSize * 1.2f * 1.2f * 1.2f;
+ case FDE_CSSPROPERTYVALUE_Larger:
+ return fCurFontSize * 1.2f;
+ case FDE_CSSPROPERTYVALUE_Smaller:
+ return fCurFontSize / 1.2f;
+ default:
+ return fCurFontSize;
+ }
+}
+FDE_CSSVERTICALALIGN CFDE_CSSStyleSelector::ToVerticalAlign(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Baseline:
+ return FDE_CSSVERTICALALIGN_Baseline;
+ case FDE_CSSPROPERTYVALUE_Middle:
+ return FDE_CSSVERTICALALIGN_Middle;
+ case FDE_CSSPROPERTYVALUE_Bottom:
+ return FDE_CSSVERTICALALIGN_Bottom;
+ case FDE_CSSPROPERTYVALUE_Super:
+ return FDE_CSSVERTICALALIGN_Super;
+ case FDE_CSSPROPERTYVALUE_Sub:
+ return FDE_CSSVERTICALALIGN_Sub;
+ case FDE_CSSPROPERTYVALUE_Top:
+ return FDE_CSSVERTICALALIGN_Top;
+ case FDE_CSSPROPERTYVALUE_TextTop:
+ return FDE_CSSVERTICALALIGN_TextTop;
+ case FDE_CSSPROPERTYVALUE_TextBottom:
+ return FDE_CSSVERTICALALIGN_TextBottom;
+ default:
+ return FDE_CSSVERTICALALIGN_Baseline;
+ }
+}
+FDE_CSSLISTSTYLETYPE CFDE_CSSStyleSelector::ToListStyleType(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSLISTSTYLETYPE_None;
+ case FDE_CSSPROPERTYVALUE_Disc:
+ return FDE_CSSLISTSTYLETYPE_Disc;
+ case FDE_CSSPROPERTYVALUE_Circle:
+ return FDE_CSSLISTSTYLETYPE_Circle;
+ case FDE_CSSPROPERTYVALUE_Square:
+ return FDE_CSSLISTSTYLETYPE_Square;
+ case FDE_CSSPROPERTYVALUE_Decimal:
+ return FDE_CSSLISTSTYLETYPE_Decimal;
+ case FDE_CSSPROPERTYVALUE_DecimalLeadingZero:
+ return FDE_CSSLISTSTYLETYPE_DecimalLeadingZero;
+ case FDE_CSSPROPERTYVALUE_LowerRoman:
+ return FDE_CSSLISTSTYLETYPE_LowerRoman;
+ case FDE_CSSPROPERTYVALUE_UpperRoman:
+ return FDE_CSSLISTSTYLETYPE_UpperRoman;
+ case FDE_CSSPROPERTYVALUE_LowerGreek:
+ return FDE_CSSLISTSTYLETYPE_LowerGreek;
+ case FDE_CSSPROPERTYVALUE_LowerLatin:
+ return FDE_CSSLISTSTYLETYPE_LowerLatin;
+ case FDE_CSSPROPERTYVALUE_UpperLatin:
+ return FDE_CSSLISTSTYLETYPE_UpperLatin;
+ case FDE_CSSPROPERTYVALUE_Armenian:
+ return FDE_CSSLISTSTYLETYPE_Armenian;
+ case FDE_CSSPROPERTYVALUE_Georgian:
+ return FDE_CSSLISTSTYLETYPE_Georgian;
+ case FDE_CSSPROPERTYVALUE_LowerAlpha:
+ return FDE_CSSLISTSTYLETYPE_LowerAlpha;
+ case FDE_CSSPROPERTYVALUE_UpperAlpha:
+ return FDE_CSSLISTSTYLETYPE_UpperAlpha;
+ case FDE_CSSPROPERTYVALUE_CjkIdeographic:
+ return FDE_CSSLISTSTYLETYPE_CjkIdeographic;
+ case FDE_CSSPROPERTYVALUE_Hebrew:
+ return FDE_CSSLISTSTYLETYPE_Hebrew;
+ case FDE_CSSLISTSTYLETYPE_Hiragana:
+ return FDE_CSSLISTSTYLETYPE_Hiragana;
+ case FDE_CSSLISTSTYLETYPE_HiraganaIroha:
+ return FDE_CSSLISTSTYLETYPE_HiraganaIroha;
+ case FDE_CSSLISTSTYLETYPE_Katakana:
+ return FDE_CSSLISTSTYLETYPE_Katakana;
+ case FDE_CSSLISTSTYLETYPE_KatakanaIroha:
+ return FDE_CSSLISTSTYLETYPE_KatakanaIroha;
+ default:
+ return FDE_CSSLISTSTYLETYPE_Disc;
+ }
+}
+FDE_CSSLISTSTYLEPOSITION CFDE_CSSStyleSelector::ToListStylePosition(FDE_CSSPROPERTYVALUE eValue)
+{
+ return eValue == FDE_CSSPROPERTYVALUE_Inside ? FDE_CSSLISTSTYLEPOSITION_Inside : FDE_CSSLISTSTYLEPOSITION_Outside;
+}
+FDE_CSSVISIBILITY CFDE_CSSStyleSelector::ToVisibility(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Visible:
+ return FDE_CSSVISIBILITY_Visible;
+ case FDE_CSSPROPERTYVALUE_Hidden:
+ return FDE_CSSVISIBILITY_Hidden;
+ case FDE_CSSPROPERTYVALUE_Collapse:
+ return FDE_CSSVISIBILITY_Collapse;
+ default:
+ return FDE_CSSVISIBILITY_Visible;
+ }
+}
+FDE_CSSWHITESPACE CFDE_CSSStyleSelector::ToWhiteSpace(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_Normal:
+ return FDE_CSSWHITESPACE_Normal;
+ case FDE_CSSPROPERTYVALUE_Pre:
+ return FDE_CSSWHITESPACE_Pre;
+ case FDE_CSSPROPERTYVALUE_Nowrap:
+ return FDE_CSSWHITESPACE_Nowrap;
+ case FDE_CSSPROPERTYVALUE_PreWrap:
+ return FDE_CSSWHITESPACE_PreWrap;
+ case FDE_CSSPROPERTYVALUE_PreLine:
+ return FDE_CSSWHITESPACE_PreLine;
+ default:
+ return FDE_CSSWHITESPACE_Normal;
+ }
+}
+FX_DWORD CFDE_CSSStyleSelector::ToTextDecoration(IFDE_CSSValueList *pValue)
+{
+ FX_DWORD dwDecoration = 0;
+ for (FX_INT32 i = pValue->CountValues() - 1; i >= 0; --i) {
+ IFDE_CSSPrimitiveValue *pPrimitive = (IFDE_CSSPrimitiveValue*)pValue->GetValue(i);
+ if (pPrimitive->GetPrimitiveType() == FDE_CSSPRIMITIVETYPE_Enum) {
+ switch (pPrimitive->GetEnum()) {
+ case FDE_CSSPROPERTYVALUE_Underline:
+ dwDecoration |= FDE_CSSTEXTDECORATION_Underline;
+ break;
+ case FDE_CSSPROPERTYVALUE_LineThrough:
+ dwDecoration |= FDE_CSSTEXTDECORATION_LineThrough;
+ break;
+ case FDE_CSSPROPERTYVALUE_Overline:
+ dwDecoration |= FDE_CSSTEXTDECORATION_Overline;
+ break;
+ case FDE_CSSPROPERTYVALUE_Blink:
+ dwDecoration |= FDE_CSSTEXTDECORATION_Blink;
+ break;
+ case FDE_CSSPROPERTYVALUE_Double:
+ dwDecoration |= FDE_CSSTEXTDECORATION_Double;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ return dwDecoration;
+}
+FDE_CSSTEXTTRANSFORM CFDE_CSSStyleSelector::ToTextTransform(FDE_CSSPROPERTYVALUE eValue)
+{
+ switch (eValue) {
+ case FDE_CSSPROPERTYVALUE_None:
+ return FDE_CSSTEXTTRANSFORM_None;
+ case FDE_CSSPROPERTYVALUE_Capitalize:
+ return FDE_CSSTEXTTRANSFORM_Capitalize;
+ case FDE_CSSPROPERTYVALUE_Uppercase:
+ return FDE_CSSTEXTTRANSFORM_UpperCase;
+ case FDE_CSSPROPERTYVALUE_Lowercase:
+ return FDE_CSSTEXTTRANSFORM_LowerCase;
+ default:
+ return FDE_CSSTEXTTRANSFORM_None;
+ }
+}
+FDE_CSSFONTVARIANT CFDE_CSSStyleSelector::ToFontVariant(FDE_CSSPROPERTYVALUE eValue)
+{
+ return eValue == FDE_CSSPROPERTYVALUE_SmallCaps ? FDE_CSSFONTVARIANT_SmallCaps : FDE_CSSFONTVARIANT_Normal;
+}
diff --git a/xfa/src/fdp/src/css/fde_cssstyleselector.h b/xfa/src/fdp/src/css/fde_cssstyleselector.h
new file mode 100644
index 0000000000..4100299664
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssstyleselector.h
@@ -0,0 +1,1000 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSSTYLESELECTOR
+#define _FDE_CSSSTYLESELECTOR
+#define FDE_CSSUNIVERSALHASH ('*')
+typedef struct _FDE_CSSRULEDATA : public CFX_Target {
+public:
+ _FDE_CSSRULEDATA(IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl, FX_DWORD dwPos);
+ IFDE_CSSSelector *pSelector;
+ IFDE_CSSDeclaration *pDeclaration;
+ FX_DWORD dwPriority;
+ _FDE_CSSRULEDATA *pNext;
+} FDE_CSSRULEDATA, * FDE_LPCSSRULEDATA;
+typedef CFX_ArrayTemplate<FDE_LPCSSRULEDATA> CFDE_CSSRuleDataArray;
+class CFDE_CSSRuleCollection : public CFX_Target
+{
+public:
+ CFDE_CSSRuleCollection() : m_pStaticStore(NULL), m_pUniversalRules(NULL) , m_iSelectors(0), m_pPersudoRules(NULL) { }
+ ~CFDE_CSSRuleCollection()
+ {
+ Clear();
+ }
+ void AddRulesFrom(const CFDE_CSSStyleSheetArray &sheets, FX_DWORD dwMediaList, IFX_FontMgr *pFontMgr);
+ void Clear();
+
+ FX_INT32 CountSelectors() const
+ {
+ return m_iSelectors;
+ }
+ FDE_LPCSSRULEDATA GetIDRuleData(FX_DWORD dwIDHash)
+ {
+ FX_LPVOID pData;
+ return m_IDRules.Lookup((FX_LPVOID)(FX_UINTPTR)dwIDHash, pData) ? (FDE_LPCSSRULEDATA)pData : NULL;
+ }
+ FDE_LPCSSRULEDATA GetTagRuleData(FX_DWORD dwTagHasn)
+ {
+ FX_LPVOID pData;
+ return m_TagRules.Lookup((FX_LPVOID)(FX_UINTPTR)dwTagHasn, pData) ? (FDE_LPCSSRULEDATA)pData : NULL;
+ }
+ FDE_LPCSSRULEDATA GetClassRuleData(FX_DWORD dwIDHash)
+ {
+ FX_LPVOID pData;
+ return m_ClassRules.Lookup((FX_LPVOID)(FX_UINTPTR)dwIDHash, pData) ? (FDE_LPCSSRULEDATA)pData : NULL;
+ }
+ FDE_LPCSSRULEDATA GetUniversalRuleData()
+ {
+ return m_pUniversalRules;
+ }
+ FDE_LPCSSRULEDATA GetPersudoRuleData()
+ {
+ return m_pPersudoRules;
+ }
+ IFX_MEMAllocator *m_pStaticStore;
+protected:
+ void AddRulesFrom(IFDE_CSSStyleSheet *pStyleSheet, IFDE_CSSRule *pRule, FX_DWORD dwMediaList, IFX_FontMgr *pFontMgr);
+ void AddRuleTo(CFX_MapPtrToPtr &map, FX_DWORD dwKey, IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl);
+ FX_BOOL AddRuleTo(FDE_LPCSSRULEDATA &pList, FDE_LPCSSRULEDATA pData);
+ FDE_LPCSSRULEDATA NewRuleData(IFDE_CSSSelector *pSel, IFDE_CSSDeclaration *pDecl);
+ CFX_MapPtrToPtr m_IDRules;
+ CFX_MapPtrToPtr m_TagRules;
+ CFX_MapPtrToPtr m_ClassRules;
+ FDE_LPCSSRULEDATA m_pUniversalRules;
+ FDE_LPCSSRULEDATA m_pPersudoRules;
+ FX_INT32 m_iSelectors;
+};
+class CFDE_CSSAccelerator;
+class CFDE_CSSComputedStyle;
+class CFDE_CSSStyleSelector : public IFDE_CSSStyleSelector, public CFX_Target
+{
+public:
+ CFDE_CSSStyleSelector();
+ ~CFDE_CSSStyleSelector();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual void SetFontMgr(IFX_FontMgr *pFontMgr);
+ virtual void SetDefFontSize(FX_FLOAT fFontSize);
+
+ virtual FX_BOOL SetStyleSheet(FDE_CSSSTYLESHEETGROUP eType, IFDE_CSSStyleSheet *pSheet);
+ virtual FX_BOOL SetStyleSheets(FDE_CSSSTYLESHEETGROUP eType, const CFDE_CSSStyleSheetArray *pArray);
+ virtual void SetStylePriority(FDE_CSSSTYLESHEETGROUP eType, FDE_CSSSTYLESHEETPRIORITY ePriority);
+ virtual void UpdateStyleIndex(FX_DWORD dwMediaList);
+ virtual IFDE_CSSAccelerator* InitAccelerator();
+ virtual IFDE_CSSComputedStyle* CreateComputedStyle(IFDE_CSSComputedStyle *pParentStyle);
+ virtual FX_INT32 MatchDeclarations(IFDE_CSSTagProvider *pTag, CFDE_CSSDeclarationArray &matchedDecls, FDE_CSSPERSUDO ePersudoType = FDE_CSSPERSUDO_NONE);
+ virtual void ComputeStyle(IFDE_CSSTagProvider *pTag, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle);
+protected:
+ void Reset();
+ void MatchRules(FDE_LPCSSTAGCACHE pCache, FDE_LPCSSRULEDATA pList, FDE_CSSPERSUDO ePersudoType);
+ void SortRulesTo(CFDE_CSSDeclarationArray &matchDecls);
+ FX_BOOL MatchSelector(FDE_LPCSSTAGCACHE pCache, IFDE_CSSSelector *pSel, FDE_CSSPERSUDO ePersudoType);
+ void AppendInlineStyle(CFDE_CSSDeclaration *pDecl, FX_LPCWSTR psz, FX_INT32 iLen);
+ void ApplyDeclarations(FX_BOOL bPriority, const IFDE_CSSDeclaration **ppDeclArray, FX_INT32 iDeclCount, IFDE_CSSComputedStyle *pDestStyle);
+ void ApplyProperty(FDE_CSSPROPERTY eProperty, IFDE_CSSValue *pValue, CFDE_CSSComputedStyle *pComputedStyle);
+
+ FX_FLOAT ApplyNumber(FDE_CSSPRIMITIVETYPE eUnit, FX_FLOAT fValue, FX_FLOAT fPercentBase);
+ FX_BOOL SetLengthWithPercent(FDE_CSSLENGTH &width, FDE_CSSPRIMITIVETYPE eType, IFDE_CSSPrimitiveValue *pPrimitive, FX_FLOAT fFontSize);
+ FX_FLOAT ToFontSize(FDE_CSSPROPERTYVALUE eValue, FX_FLOAT fCurFontSize);
+ FDE_CSSDISPLAY ToDisplay(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSTEXTALIGN ToTextAlign(FDE_CSSPROPERTYVALUE eValue);
+ FX_WORD ToFontWeight(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSFONTSTYLE ToFontStyle(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSBORDERSTYLE ToBorderStyle(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSVERTICALALIGN ToVerticalAlign(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSLISTSTYLETYPE ToListStyleType(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSLISTSTYLEPOSITION ToListStylePosition(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSVISIBILITY ToVisibility(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSWHITESPACE ToWhiteSpace(FDE_CSSPROPERTYVALUE eValue);
+ FX_DWORD ToTextDecoration(IFDE_CSSValueList *pList);
+ FDE_CSSTEXTTRANSFORM ToTextTransform(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSFONTVARIANT ToFontVariant(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSFLOAT ToFloat(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSCLEAR ToClear(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSWRITINGMODE ToWritingMode(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSWORDBREAK ToWordBreak(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSPAGEBREAK ToPageBreak(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSOVERFLOW ToOverflow(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSLINEBREAK ToLineBreak(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSTEXTCOMBINE ToTextCombine(FDE_CSSPROPERTYVALUE eValue);
+ FX_BOOL ToTextEmphasisMark(FDE_CSSPROPERTYVALUE eValue, FDE_CSSTEXTEMPHASISMARK &eMark);
+ FX_BOOL ToTextEmphasisFill(FDE_CSSPROPERTYVALUE eValue, FDE_CSSTEXTEMPHASISFILL &eFill);
+ FDE_CSSCURSOR ToCursor(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSPOSITION ToPosition(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSCAPTIONSIDE ToCaptionSide(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSBKGREPEAT ToBKGRepeat(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSBKGATTACHMENT ToBKGAttachment(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSRUBYALIGN ToRubyAlign(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSRUBYOVERHANG ToRubyOverhang(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSRUBYPOSITION ToRubyPosition(FDE_CSSPROPERTYVALUE eValue);
+ FDE_CSSRUBYSPAN ToRubySpan(FDE_CSSPROPERTYVALUE eValue);
+ IFX_FontMgr *m_pFontMgr;
+ FX_FLOAT m_fDefFontSize;
+ IFX_MEMAllocator *m_pRuleDataStore;
+ CFDE_CSSStyleSheetArray m_SheetGroups[FDE_CSSSTYLESHEETGROUP_MAX];
+ CFDE_CSSRuleCollection m_RuleCollection[FDE_CSSSTYLESHEETGROUP_MAX];
+ FDE_CSSSTYLESHEETGROUP m_ePriorities[FDE_CSSSTYLESHEETPRIORITY_MAX];
+ IFX_MEMAllocator *m_pInlineStyleStore;
+ IFX_MEMAllocator *m_pFixedStyleStore;
+ CFDE_CSSAccelerator *m_pAccelerator;
+ CFDE_CSSRuleDataArray m_MatchedRules;
+};
+typedef struct _FDE_CSSCOUNTERDATA {
+public:
+ _FDE_CSSCOUNTERDATA()
+ {
+ FX_memset(this, 0, sizeof(_FDE_CSSCOUNTERDATA));
+ }
+ FX_BOOL GetCounterIncrement(FX_INT32 &iValue)
+ {
+ iValue = m_iIncVal;
+ return m_bIncrement;
+ }
+ FX_BOOL GetCounterReset(FX_INT32 &iValue)
+ {
+ iValue = m_iResetVal;
+ return m_bReset;
+ }
+ FX_LPCWSTR m_pszIdent;
+ FX_BOOL m_bIncrement;
+ FX_BOOL m_bReset;
+ FX_INT32 m_iIncVal;
+ FX_INT32 m_iResetVal;
+} FDE_CSSCOUNTERDATA, *FDE_LPCSSCOUNTERDATA;
+class CFDE_CSSCounterStyle
+{
+public:
+ CFDE_CSSCounterStyle(): m_pCounterInc(NULL), m_pCounterReset(NULL) {}
+ void SetCounterIncrementList(IFDE_CSSValueList *pList)
+ {
+ m_pCounterInc = pList;
+ m_bIndexDirty = TRUE;
+ }
+ void SetCounterResetList(IFDE_CSSValueList *pList)
+ {
+ m_pCounterReset = pList;
+ m_bIndexDirty = TRUE;
+ }
+ FX_INT32 CountCounters()
+ {
+ UpdateIndex();
+ return m_arrCounterData.GetSize();
+ }
+ FX_BOOL GetCounterIncrement(FX_INT32 index, FX_INT32 &iValue)
+ {
+ UpdateIndex();
+ return m_arrCounterData.ElementAt(index).GetCounterIncrement(iValue);
+ }
+ FX_BOOL GetCounterReset(FX_INT32 index, FX_INT32 &iValue)
+ {
+ UpdateIndex();
+ return m_arrCounterData.ElementAt(index).GetCounterReset(iValue);
+ }
+ FX_LPCWSTR GetCounterIdentifier(FX_INT32 index)
+ {
+ UpdateIndex();
+ return m_arrCounterData.ElementAt(index).m_pszIdent;
+ }
+protected:
+ void UpdateIndex();
+ void DoUpdateIndex(IFDE_CSSValueList *pList);
+ FX_INT32 FindIndex(FX_LPCWSTR pszIdentifier);
+ IFDE_CSSValueList *m_pCounterInc;
+ IFDE_CSSValueList *m_pCounterReset;
+ CFX_ArrayTemplate<FDE_CSSCOUNTERDATA> m_arrCounterData;
+ FX_BOOL m_bIndexDirty;
+};
+class CFDE_CSSInheritedData
+{
+public:
+ void Reset()
+ {
+ FX_memset(this, 0, sizeof(CFDE_CSSInheritedData));
+ m_LetterSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
+ m_WordSpacing.Set(FDE_CSSLENGTHUNIT_Normal);
+ m_TextIndent.Set(FDE_CSSLENGTHUNIT_Point, 0);
+ m_fFontSize = 12.0f;
+ m_fLineHeight = 14.0f;
+ m_wFontWeight = 400;
+ m_dwFontColor = 0xFF000000;
+ m_iWidows = 2;
+ m_bTextEmphasisColorCurrent = TRUE;
+ m_iOrphans = 2;
+ }
+ FX_LPCWSTR m_pszListStyleImage;
+ FDE_CSSLENGTH m_LetterSpacing;
+ FDE_CSSLENGTH m_WordSpacing;
+ FDE_CSSLENGTH m_TextIndent;
+ IFDE_CSSValueList *m_pFontFamily;
+ IFDE_CSSValueList *m_pQuotes;
+ IFDE_CSSValueList *m_pCursorUris;
+ FDE_CSSCURSOR m_eCursor;
+ FX_FLOAT m_fFontSize;
+ FX_FLOAT m_fLineHeight;
+ FX_ARGB m_dwFontColor;
+ FX_ARGB m_dwTextEmphasisColor;
+ FX_WORD m_wFontWeight;
+ FX_INT32 m_iWidows;
+ FX_INT32 m_iOrphans;
+ FX_LPCWSTR m_pszTextEmphasisCustomMark;
+ FX_WORD m_eFontVariant : 1;
+ FX_WORD m_eFontStyle : 1;
+ FX_WORD m_bTextEmphasisColorCurrent: 1;
+ FX_WORD m_eTextAligh : 2;
+ FX_WORD m_eVisibility : 2;
+ FX_WORD m_eWhiteSpace : 3;
+ FX_WORD m_eTextTransform : 2;
+ FX_WORD m_eWritingMode : 2;
+ FX_WORD m_eWordBreak : 2;
+ FX_WORD m_eLineBreak : 2;
+ FX_WORD m_eTextEmphasisFill : 1;
+ FX_WORD m_eTextEmphasisMark : 3;
+ FX_WORD m_eCaptionSide : 3;
+
+ FX_WORD m_eRubyAlign : 4;
+ FX_WORD m_eRubyOverhang : 2;
+ FX_WORD m_eRubyPosition : 2;
+};
+class CFDE_CSSNonInheritedData
+{
+public:
+ void Reset()
+ {
+ FX_memset(this, 0, sizeof(CFDE_CSSNonInheritedData));
+ m_MarginWidth = m_BorderWidth = m_PaddingWidth.Set(FDE_CSSLENGTHUNIT_Point, 0);
+ m_MinBoxSize.Set(FDE_CSSLENGTHUNIT_Point, 0);
+ m_MaxBoxSize.Set(FDE_CSSLENGTHUNIT_None);
+ m_eDisplay = FDE_CSSDISPLAY_Inline;
+ m_fVerticalAlign = 0.0f;
+ m_ColumnCount.Set(FDE_CSSLENGTHUNIT_Auto);
+ m_ColumnGap.Set(FDE_CSSLENGTHUNIT_Normal);
+ m_bColumnRuleColorSame = TRUE;
+ m_ColumnWidth.Set(FDE_CSSLENGTHUNIT_Auto);
+ m_ColumnRuleWidth.Set(FDE_CSSLENGTHUNIT_Auto);
+ m_eTextCombine = FDE_CSSTEXTCOMBINE_None;
+ }
+
+ IFDE_CSSValueList *m_pContentList;
+ CFDE_CSSCounterStyle *m_pCounterStyle;
+ FDE_CSSRECT m_MarginWidth;
+ FDE_CSSRECT m_BorderWidth;
+ FDE_CSSRECT m_PaddingWidth;
+ FDE_CSSSIZE m_BoxSize;
+ FDE_CSSSIZE m_MinBoxSize;
+ FDE_CSSSIZE m_MaxBoxSize;
+ FDE_CSSPOINT m_BKGPosition;
+ FX_LPCWSTR m_pszBKGImage;
+ FX_ARGB m_dwBKGColor;
+ FX_ARGB m_dwBDRLeftColor;
+ FX_ARGB m_dwBDRTopColor;
+ FX_ARGB m_dwBDRRightColor;
+ FX_ARGB m_dwBDRBottomColor;
+ IFDE_CSSValue *m_pRubySpan;
+ FDE_CSSLENGTH m_ColumnCount;
+ FDE_CSSLENGTH m_ColumnGap;
+ FDE_CSSLENGTH m_ColumnRuleWidth;
+ FDE_CSSLENGTH m_ColumnWidth;
+ FX_ARGB m_dwColumnRuleColor;
+ FDE_CSSLENGTH m_Top;
+ FDE_CSSLENGTH m_Bottom;
+ FDE_CSSLENGTH m_Left;
+ FDE_CSSLENGTH m_Right;
+
+ FX_FLOAT m_fVerticalAlign;
+ FX_FLOAT m_fTextCombineNumber;
+ FX_DWORD m_eBDRLeftStyle : 4;
+ FX_DWORD m_eBDRTopStyle : 4;
+ FX_DWORD m_eBDRRightStyle : 4;
+ FX_DWORD m_eBDRBottomStyle : 4;
+ FX_DWORD m_eDisplay : 5;
+ FX_DWORD m_eVerticalAlign : 4;
+ FX_DWORD m_eListStyleType : 5;
+ FX_DWORD m_eColumnRuleStyle : 4;
+ FX_DWORD m_ePageBreakInside : 3;
+ FX_DWORD m_ePageBreakAfter : 3;
+ FX_DWORD m_ePageBreakBefore : 3;
+ FX_DWORD m_ePosition : 2;
+ FX_DWORD m_eBKGRepeat : 2;
+ FX_DWORD m_eFloat : 2;
+ FX_DWORD m_eClear : 2;
+ FX_DWORD m_eOverflowX : 3;
+ FX_DWORD m_eOverflowY : 3;
+ FX_DWORD m_eListStylePosition: 1;
+ FX_DWORD m_eBKGAttachment : 1;
+ FX_DWORD m_bHasMargin : 1;
+ FX_DWORD m_bHasBorder : 1;
+ FX_DWORD m_bHasPadding : 1;
+ FX_DWORD m_dwTextDecoration : 5;
+ FX_DWORD m_eTextCombine : 1;
+ FX_DWORD m_bColumnRuleColorSame : 1;
+ FX_DWORD m_bHasTextCombineNumber : 1;
+};
+class CFDE_CSSComputedStyle : public IFDE_CSSComputedStyle, public IFDE_CSSFontStyle,
+ public IFDE_CSSBoundaryStyle, public IFDE_CSSPositionStyle,
+ public IFDE_CSSParagraphStyle, public IFDE_CSSBackgroundStyle,
+ public IFDE_CSSVisualStyle, public IFDE_CSSListStyle,
+ public IFDE_CSSMultiColumnStyle, public IFDE_CSSGeneratedContentStyle,
+ public IFDE_CSSTableStyle, public IFDE_CSSRubyStyle,
+ public CFX_Target
+{
+public:
+ CFDE_CSSComputedStyle(IFX_MEMAllocator *pAlloc) : m_dwRefCount(1), m_pAllocator(pAlloc) {}
+ ~CFDE_CSSComputedStyle() {}
+ virtual FX_DWORD AddRef()
+ {
+ return ++m_dwRefCount;
+ }
+ virtual FX_DWORD Release()
+ {
+ FX_DWORD dwRefCount = --m_dwRefCount;
+ if (dwRefCount == 0) {
+ if (m_NonInheritedData.m_pCounterStyle != NULL) {
+ FDE_Delete m_NonInheritedData.m_pCounterStyle;
+ }
+ FDE_DeleteWith(CFDE_CSSComputedStyle, m_pAllocator, this);
+ }
+ return dwRefCount;
+ }
+
+ virtual void Reset()
+ {
+ m_InheritedData.Reset();
+ m_NonInheritedData.Reset();
+ }
+ virtual IFDE_CSSFontStyle* GetFontStyles() const
+ {
+ return (IFDE_CSSFontStyle * const)this;
+ }
+ virtual IFDE_CSSBoundaryStyle* GetBoundaryStyles() const
+ {
+ return (IFDE_CSSBoundaryStyle * const)this;
+ }
+ virtual IFDE_CSSPositionStyle* GetPositionStyles() const
+ {
+ return (IFDE_CSSPositionStyle * const)this;
+ }
+ virtual IFDE_CSSParagraphStyle* GetParagraphStyles() const
+ {
+ return (IFDE_CSSParagraphStyle * const)this;
+ }
+ virtual IFDE_CSSBackgroundStyle* GetBackgroundStyles() const
+ {
+ return (IFDE_CSSBackgroundStyle * const)this;
+ }
+ virtual IFDE_CSSVisualStyle* GetVisualStyles() const
+ {
+ return (IFDE_CSSVisualStyle * const)this;
+ }
+ virtual IFDE_CSSListStyle* GetListStyles() const
+ {
+ return (IFDE_CSSListStyle * const)this;
+ }
+ virtual IFDE_CSSTableStyle* GetTableStyle() const
+ {
+ return (IFDE_CSSTableStyle * const)this;
+ }
+ virtual IFDE_CSSMultiColumnStyle* GetMultiColumnStyle() const
+ {
+ return (IFDE_CSSMultiColumnStyle * const)this;
+ }
+ virtual IFDE_CSSGeneratedContentStyle* GetGeneratedContentStyle() const
+ {
+ return (IFDE_CSSGeneratedContentStyle * const)this;
+ }
+ virtual IFDE_CSSRubyStyle* GetRubyStyle() const
+ {
+ return (IFDE_CSSRubyStyle * const)this;
+ }
+ virtual FX_BOOL GetCustomStyle(FX_WSTR wsName, CFX_WideString &wsValue) const
+ {
+ for (FX_INT32 i = m_CustomProperties.GetSize() - 2; i > -1; i -= 2) {
+ if (wsName == m_CustomProperties[i]) {
+ wsValue = m_CustomProperties[i + 1];
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ virtual FDE_CSSRUBYALIGN GetRubyAlign() const
+ {
+ return (FDE_CSSRUBYALIGN)m_InheritedData.m_eRubyAlign;
+ }
+ virtual FDE_CSSRUBYPOSITION GetRubyPosition() const
+ {
+ return (FDE_CSSRUBYPOSITION)m_InheritedData.m_eRubyPosition;
+ }
+ virtual FDE_CSSRUBYOVERHANG GetRubyOverhang() const
+ {
+ return (FDE_CSSRUBYOVERHANG)m_InheritedData.m_eRubyOverhang;
+ }
+ virtual FDE_CSSRUBYSPAN GetRubySpanType() const
+ {
+ return m_NonInheritedData.m_pRubySpan == NULL ? FDE_CSSRUBYSPAN_None : FDE_CSSRUBYSPAN_Attr;
+ }
+ virtual IFDE_CSSValue* GetRubySpanAttr() const
+ {
+ return m_NonInheritedData.m_pRubySpan;
+ }
+ virtual FDE_CSSCAPTIONSIDE GetCaptionSide() const
+ {
+ return (FDE_CSSCAPTIONSIDE)m_InheritedData.m_eCaptionSide;
+ }
+ virtual FX_INT32 CountCounters()
+ {
+ return (m_NonInheritedData.m_pCounterStyle == NULL) ? 0 : m_NonInheritedData.m_pCounterStyle->CountCounters();
+ }
+ virtual FX_LPCWSTR GetCounterIdentifier(FX_INT32 index)
+ {
+ return m_NonInheritedData.m_pCounterStyle->GetCounterIdentifier(index);
+ }
+ virtual FX_BOOL GetCounterReset(FX_INT32 index, FX_INT32 &iValue)
+ {
+ return m_NonInheritedData.m_pCounterStyle->GetCounterReset(index, iValue);
+ }
+ virtual FX_BOOL GetCounterIncrement(FX_INT32 index, FX_INT32 &iValue)
+ {
+ return m_NonInheritedData.m_pCounterStyle->GetCounterIncrement(index, iValue);
+ }
+ virtual IFDE_CSSValueList* GetContent() const
+ {
+ return m_NonInheritedData.m_pContentList;
+ }
+ virtual FX_INT32 CountQuotes() const
+ {
+ return m_InheritedData.m_pQuotes == NULL ? 0 : m_InheritedData.m_pQuotes->CountValues();
+ }
+ virtual FX_LPCWSTR GetQuotes(FX_INT32 index) const
+ {
+ FXSYS_assert(m_InheritedData.m_pQuotes != NULL && m_InheritedData.m_pQuotes->CountValues() > index);
+ return ((IFDE_CSSPrimitiveValue*)(m_InheritedData.m_pQuotes->GetValue(index)))->GetString(index);
+ }
+ virtual const FDE_CSSLENGTH& GetColumnCount() const
+ {
+ return m_NonInheritedData.m_ColumnCount;
+ }
+ virtual const FDE_CSSLENGTH& GetColumnGap() const
+ {
+ return m_NonInheritedData.m_ColumnGap;
+ }
+ virtual FX_ARGB GetColumnRuleColor() const
+ {
+ return m_NonInheritedData.m_bColumnRuleColorSame ? m_InheritedData.m_dwFontColor : m_NonInheritedData.m_dwColumnRuleColor;
+ }
+ virtual FDE_CSSBORDERSTYLE GetColumnRuleStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eColumnRuleStyle;
+ }
+ virtual const FDE_CSSLENGTH& GetColumnRuleWidth() const
+ {
+ return m_NonInheritedData.m_ColumnRuleWidth;
+ }
+ virtual const FDE_CSSLENGTH& GetColumnWidth() const
+ {
+ return m_NonInheritedData.m_ColumnWidth;
+ }
+ virtual void SetColumnCount(const FDE_CSSLENGTH &columnCount)
+ {
+ m_NonInheritedData.m_ColumnCount = columnCount;
+ }
+ virtual void SetColumnGap(const FDE_CSSLENGTH &columnGap)
+ {
+ m_NonInheritedData.m_ColumnGap = columnGap;
+ }
+ virtual void SetColumnRuleColor(FX_ARGB dwColumnRuleColor)
+ {
+ m_NonInheritedData.m_dwColumnRuleColor = dwColumnRuleColor, m_NonInheritedData.m_bColumnRuleColorSame = FALSE;
+ }
+ virtual void SetColumnRuleStyle(FDE_CSSBORDERSTYLE eColumnRuleStyle)
+ {
+ m_NonInheritedData.m_eColumnRuleStyle = eColumnRuleStyle;
+ }
+ virtual void SetColumnRuleWidth(const FDE_CSSLENGTH &columnRuleWidth)
+ {
+ m_NonInheritedData.m_ColumnRuleWidth = columnRuleWidth;
+ }
+ virtual void SetColumnWidth(const FDE_CSSLENGTH &columnWidth)
+ {
+ m_NonInheritedData.m_ColumnWidth = columnWidth;
+ }
+ virtual FX_INT32 CountFontFamilies() const
+ {
+ return m_InheritedData.m_pFontFamily ? m_InheritedData.m_pFontFamily->CountValues() : 0;
+ }
+ virtual FX_LPCWSTR GetFontFamily(FX_INT32 index) const
+ {
+ return ((IFDE_CSSPrimitiveValue*)(m_InheritedData.m_pFontFamily->GetValue(index)))->GetString(index);
+ }
+ virtual FX_WORD GetFontWeight() const
+ {
+ return m_InheritedData.m_wFontWeight;
+ }
+ virtual FDE_CSSFONTVARIANT GetFontVariant() const
+ {
+ return (FDE_CSSFONTVARIANT)m_InheritedData.m_eFontVariant;
+ }
+ virtual FDE_CSSFONTSTYLE GetFontStyle() const
+ {
+ return (FDE_CSSFONTSTYLE)m_InheritedData.m_eFontStyle;
+ }
+ virtual FX_FLOAT GetFontSize() const
+ {
+ return m_InheritedData.m_fFontSize;
+ }
+ virtual FX_ARGB GetColor() const
+ {
+ return m_InheritedData.m_dwFontColor;
+ }
+ virtual void SetFontWeight(FX_WORD wFontWeight)
+ {
+ m_InheritedData.m_wFontWeight = wFontWeight;
+ }
+ virtual void SetFontVariant(FDE_CSSFONTVARIANT eFontVariant)
+ {
+ m_InheritedData.m_eFontVariant = eFontVariant;
+ }
+ virtual void SetFontStyle(FDE_CSSFONTSTYLE eFontStyle)
+ {
+ m_InheritedData.m_eFontStyle = eFontStyle;
+ }
+ virtual void SetFontSize(FX_FLOAT fFontSize)
+ {
+ m_InheritedData.m_fFontSize = fFontSize;
+ }
+ virtual void SetColor(FX_ARGB dwFontColor)
+ {
+ m_InheritedData.m_dwFontColor = dwFontColor;
+ }
+ virtual FX_ARGB GetBorderLeftColor() const
+ {
+ return m_NonInheritedData.m_dwBDRLeftColor;
+ }
+ virtual FX_ARGB GetBorderTopColor() const
+ {
+ return m_NonInheritedData.m_dwBDRTopColor;
+ }
+ virtual FX_ARGB GetBorderRightColor() const
+ {
+ return m_NonInheritedData.m_dwBDRRightColor;
+ }
+ virtual FX_ARGB GetBorderBottomColor() const
+ {
+ return m_NonInheritedData.m_dwBDRBottomColor;
+ }
+
+ virtual FDE_CSSBORDERSTYLE GetBorderLeftStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eBDRLeftStyle;
+ }
+ virtual FDE_CSSBORDERSTYLE GetBorderTopStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eBDRTopStyle;
+ }
+ virtual FDE_CSSBORDERSTYLE GetBorderRightStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eBDRRightStyle;
+ }
+ virtual FDE_CSSBORDERSTYLE GetBorderBottomStyle() const
+ {
+ return (FDE_CSSBORDERSTYLE)m_NonInheritedData.m_eBDRBottomStyle;
+ }
+
+ virtual const FDE_CSSRECT* GetBorderWidth() const
+ {
+ return m_NonInheritedData.m_bHasBorder ? &(m_NonInheritedData.m_BorderWidth) : NULL;
+ }
+ virtual const FDE_CSSRECT* GetMarginWidth() const
+ {
+ return m_NonInheritedData.m_bHasMargin ? &(m_NonInheritedData.m_MarginWidth) : NULL;
+ }
+ virtual const FDE_CSSRECT* GetPaddingWidth() const
+ {
+ return m_NonInheritedData.m_bHasPadding ? &(m_NonInheritedData.m_PaddingWidth) : NULL;
+ }
+ virtual void SetBorderLeftColor(FX_ARGB dwBorderColor)
+ {
+ m_NonInheritedData.m_dwBDRLeftColor = dwBorderColor;
+ }
+ virtual void SetBorderTopColor(FX_ARGB dwBorderColor)
+ {
+ m_NonInheritedData.m_dwBDRTopColor = dwBorderColor;
+ }
+ virtual void SetBorderRightColor(FX_ARGB dwBorderColor)
+ {
+ m_NonInheritedData.m_dwBDRRightColor = dwBorderColor;
+ }
+ virtual void SetBorderBottomColor(FX_ARGB dwBorderColor)
+ {
+ m_NonInheritedData.m_dwBDRBottomColor = dwBorderColor;
+ }
+
+ virtual void SetBorderLeftStyle(FDE_CSSBORDERSTYLE eBorderStyle)
+ {
+ m_NonInheritedData.m_eBDRLeftStyle = eBorderStyle;
+ }
+ virtual void SetBorderTopStyle(FDE_CSSBORDERSTYLE eBorderStyle)
+ {
+ m_NonInheritedData.m_eBDRTopStyle = eBorderStyle;
+ }
+ virtual void SetBorderRightStyle(FDE_CSSBORDERSTYLE eBorderStyle)
+ {
+ m_NonInheritedData.m_eBDRRightStyle = eBorderStyle;
+ }
+ virtual void SetBorderBottomStyle(FDE_CSSBORDERSTYLE eBorderStyle)
+ {
+ m_NonInheritedData.m_eBDRBottomStyle = eBorderStyle;
+ }
+
+ virtual void SetBorderWidth(const FDE_CSSRECT &rect)
+ {
+ m_NonInheritedData.m_BorderWidth = rect;
+ m_NonInheritedData.m_bHasBorder = TRUE;
+ }
+ virtual void SetMarginWidth(const FDE_CSSRECT &rect)
+ {
+ m_NonInheritedData.m_MarginWidth = rect;
+ m_NonInheritedData.m_bHasMargin = TRUE;
+ }
+ virtual void SetPaddingWidth(const FDE_CSSRECT &rect)
+ {
+ m_NonInheritedData.m_PaddingWidth = rect;
+ m_NonInheritedData.m_bHasPadding = TRUE;
+ }
+ virtual FDE_CSSDISPLAY GetDisplay() const
+ {
+ return (FDE_CSSDISPLAY)m_NonInheritedData.m_eDisplay;
+ }
+ virtual const FDE_CSSSIZE& GetBoxSize() const
+ {
+ return m_NonInheritedData.m_BoxSize;
+ }
+ virtual const FDE_CSSSIZE& GetMinBoxSize() const
+ {
+ return m_NonInheritedData.m_MinBoxSize;
+ }
+ virtual const FDE_CSSSIZE& GetMaxBoxSize() const
+ {
+ return m_NonInheritedData.m_MaxBoxSize;
+ }
+ virtual FDE_CSSFLOAT GetFloat() const
+ {
+ return (FDE_CSSFLOAT)m_NonInheritedData.m_eFloat;
+ }
+ virtual FDE_CSSCLEAR GetClear() const
+ {
+ return (FDE_CSSCLEAR)m_NonInheritedData.m_eClear;
+ }
+ virtual FDE_CSSPOSITION GetPosition() const
+ {
+ return (FDE_CSSPOSITION)m_NonInheritedData.m_ePosition;
+ }
+ virtual FDE_CSSLENGTH GetTop() const
+ {
+ return m_NonInheritedData.m_Top;
+ }
+ virtual FDE_CSSLENGTH GetBottom() const
+ {
+ return m_NonInheritedData.m_Bottom;
+ }
+ virtual FDE_CSSLENGTH GetLeft() const
+ {
+ return m_NonInheritedData.m_Left;
+ }
+ virtual FDE_CSSLENGTH GetRight() const
+ {
+ return m_NonInheritedData.m_Right;
+ }
+
+ virtual void SetDisplay(FDE_CSSDISPLAY eDisplay)
+ {
+ m_NonInheritedData.m_eDisplay = eDisplay;
+ }
+ virtual void SetBoxSize(const FDE_CSSSIZE &size)
+ {
+ m_NonInheritedData.m_BoxSize = size;
+ }
+ virtual void SetMinBoxSize(const FDE_CSSSIZE &size)
+ {
+ m_NonInheritedData.m_MinBoxSize = size;
+ }
+ virtual void SetMaxBoxSize(const FDE_CSSSIZE &size)
+ {
+ m_NonInheritedData.m_MaxBoxSize = size;
+ }
+ virtual void SetFloat(FDE_CSSFLOAT eFloat)
+ {
+ m_NonInheritedData.m_eFloat = eFloat;
+ }
+ virtual void SetClear(FDE_CSSCLEAR eClear)
+ {
+ m_NonInheritedData.m_eClear = eClear;
+ }
+ virtual FX_FLOAT GetLineHeight() const
+ {
+ return m_InheritedData.m_fLineHeight;
+ }
+ virtual FDE_CSSWHITESPACE GetWhiteSpace() const
+ {
+ return (FDE_CSSWHITESPACE)m_InheritedData.m_eWhiteSpace;
+ }
+ virtual const FDE_CSSLENGTH& GetTextIndent() const
+ {
+ return m_InheritedData.m_TextIndent;
+ }
+ virtual FDE_CSSTEXTALIGN GetTextAlign() const
+ {
+ return (FDE_CSSTEXTALIGN)m_InheritedData.m_eTextAligh;
+ }
+ virtual FDE_CSSVERTICALALIGN GetVerticalAlign() const
+ {
+ return (FDE_CSSVERTICALALIGN)m_NonInheritedData.m_eVerticalAlign;
+ }
+ virtual FX_FLOAT GetNumberVerticalAlign() const
+ {
+ return m_NonInheritedData.m_fVerticalAlign;
+ }
+ virtual FDE_CSSTEXTTRANSFORM GetTextTransform() const
+ {
+ return (FDE_CSSTEXTTRANSFORM)m_InheritedData.m_eTextTransform;
+ }
+ virtual FX_DWORD GetTextDecoration() const
+ {
+ return m_NonInheritedData.m_dwTextDecoration;
+ }
+ virtual const FDE_CSSLENGTH& GetLetterSpacing() const
+ {
+ return m_InheritedData.m_LetterSpacing;
+ }
+ virtual const FDE_CSSLENGTH& GetWordSpacing() const
+ {
+ return m_InheritedData.m_WordSpacing;
+ }
+ virtual FDE_CSSWRITINGMODE GetWritingMode() const
+ {
+ return (FDE_CSSWRITINGMODE)m_InheritedData.m_eWritingMode;
+ }
+ virtual FDE_CSSWORDBREAK GetWordBreak() const
+ {
+ return (FDE_CSSWORDBREAK)m_InheritedData.m_eWordBreak;
+ }
+ virtual FX_INT32 GetWidows() const
+ {
+ return m_InheritedData.m_iWidows;
+ }
+ virtual FX_ARGB GetTextEmphasisColor() const
+ {
+ return m_InheritedData.m_bTextEmphasisColorCurrent ? m_InheritedData.m_dwFontColor : m_InheritedData.m_dwTextEmphasisColor;
+ }
+ virtual FDE_CSSPAGEBREAK GetPageBreakBefore() const
+ {
+ return (FDE_CSSPAGEBREAK)m_NonInheritedData.m_ePageBreakBefore;
+ }
+ virtual FDE_CSSPAGEBREAK GetPageBreakAfter() const
+ {
+ return (FDE_CSSPAGEBREAK)m_NonInheritedData.m_ePageBreakAfter;
+ }
+ virtual FDE_CSSPAGEBREAK GetPageBreakInside() const
+ {
+ return (FDE_CSSPAGEBREAK)m_NonInheritedData.m_ePageBreakInside;
+ }
+ virtual FX_INT32 GetOrphans() const
+ {
+ return m_InheritedData.m_iOrphans;
+ }
+ virtual FDE_CSSLINEBREAK GetLineBreak() const
+ {
+ return (FDE_CSSLINEBREAK)m_InheritedData.m_eLineBreak;
+ }
+ virtual FDE_CSSTEXTEMPHASISMARK GetTextEmphasisMark() const;
+ virtual FDE_CSSTEXTEMPHASISFILL GetTextEmphasisFill() const
+ {
+ return (FDE_CSSTEXTEMPHASISFILL)m_InheritedData.m_eTextEmphasisFill;
+ }
+ virtual FX_LPCWSTR GetTextEmphasisCustom() const
+ {
+ FXSYS_assert(m_InheritedData.m_eTextEmphasisMark == FDE_CSSTEXTEMPHASISMARK_Custom);
+ return m_InheritedData.m_pszTextEmphasisCustomMark;
+ }
+ virtual FDE_CSSTEXTCOMBINE GetTextCombineType() const
+ {
+ return (FDE_CSSTEXTCOMBINE)m_NonInheritedData.m_eTextCombine;
+ }
+ virtual FX_BOOL HasTextCombineNumber() const
+ {
+ return m_NonInheritedData.m_bHasTextCombineNumber;
+ }
+ virtual FX_FLOAT GetTextCombineNumber() const
+ {
+ FXSYS_assert(m_NonInheritedData.m_eTextCombine == FDE_CSSTEXTCOMBINE_Horizontal);
+ return m_NonInheritedData.m_fTextCombineNumber;
+ }
+ virtual void SetLineHeight(FX_FLOAT fLineHeight)
+ {
+ m_InheritedData.m_fLineHeight = fLineHeight;
+ }
+ virtual void SetWhiteSpace(FDE_CSSWHITESPACE eWhiteSpace)
+ {
+ m_InheritedData.m_eWhiteSpace = eWhiteSpace;
+ }
+ virtual void SetTextIndent(const FDE_CSSLENGTH &textIndent)
+ {
+ m_InheritedData.m_TextIndent = textIndent;
+ }
+ virtual void SetTextAlign(FDE_CSSTEXTALIGN eTextAlign)
+ {
+ m_InheritedData.m_eTextAligh = eTextAlign;
+ }
+ virtual void SetVerticalAlign(FDE_CSSVERTICALALIGN eVerticalAlign)
+ {
+ m_NonInheritedData.m_eVerticalAlign = eVerticalAlign;
+ }
+ virtual void SetNumberVerticalAlign(FX_FLOAT fAlign)
+ {
+ m_NonInheritedData.m_eVerticalAlign = FDE_CSSVERTICALALIGN_Number, m_NonInheritedData.m_fVerticalAlign = fAlign;
+ }
+ virtual void SetTextTransform(FDE_CSSTEXTTRANSFORM eTextTransform)
+ {
+ m_InheritedData.m_eTextTransform = eTextTransform;
+ }
+ virtual void SetTextDecoration(FX_DWORD dwTextDecoration)
+ {
+ m_NonInheritedData.m_dwTextDecoration = dwTextDecoration;
+ }
+ virtual void SetLetterSpacing(const FDE_CSSLENGTH &letterSpacing)
+ {
+ m_InheritedData.m_LetterSpacing = letterSpacing;
+ }
+ virtual void SetWordSpacing(const FDE_CSSLENGTH &wordSpacing)
+ {
+ m_InheritedData.m_WordSpacing = wordSpacing;
+ }
+ virtual void SetWritingMode(FDE_CSSWRITINGMODE eWritingMode)
+ {
+ m_InheritedData.m_eWritingMode = eWritingMode;
+ }
+ virtual void SetWordBreak(FDE_CSSWORDBREAK eWordBreak)
+ {
+ m_InheritedData.m_eWordBreak = eWordBreak;
+ }
+ virtual void SetWidows(FX_INT32 iWidows)
+ {
+ m_InheritedData.m_iWidows = iWidows;
+ }
+ virtual void SetTextEmphasisColor(FX_ARGB dwTextEmphasisColor)
+ {
+ m_InheritedData.m_dwTextEmphasisColor = dwTextEmphasisColor, m_InheritedData.m_bTextEmphasisColorCurrent = FALSE;
+ }
+ virtual void SetPageBreakBefore(FDE_CSSPAGEBREAK ePageBreakBefore)
+ {
+ m_NonInheritedData.m_ePageBreakBefore = ePageBreakBefore;
+ }
+ virtual void SetPageBreakAfter(FDE_CSSPAGEBREAK ePageBreakAfter)
+ {
+ m_NonInheritedData.m_ePageBreakAfter = ePageBreakAfter;
+ }
+ virtual void SetPageBreakInside(FDE_CSSPAGEBREAK ePageBreakInside)
+ {
+ m_NonInheritedData.m_ePageBreakInside = ePageBreakInside;
+ }
+ virtual void SetOrphans(FX_INT32 iOrphans)
+ {
+ m_InheritedData.m_iOrphans = iOrphans;
+ }
+ virtual void SetLineBreak(FDE_CSSLINEBREAK eLineBreak)
+ {
+ m_InheritedData.m_eLineBreak = eLineBreak;
+ }
+ virtual FX_ARGB GetBKGColor() const
+ {
+ return m_NonInheritedData.m_dwBKGColor;
+ }
+ virtual FX_LPCWSTR GetBKGImage() const
+ {
+ return m_NonInheritedData.m_pszBKGImage;
+ }
+ virtual const FDE_CSSPOINT& GetBKGPosition() const
+ {
+ return m_NonInheritedData.m_BKGPosition;
+ }
+ virtual FDE_CSSBKGREPEAT GetBKGRepeat() const
+ {
+ return (FDE_CSSBKGREPEAT)m_NonInheritedData.m_eBKGRepeat;
+ }
+ virtual FDE_CSSBKGATTACHMENT GetBKGAttachment() const
+ {
+ return (FDE_CSSBKGATTACHMENT)m_NonInheritedData.m_eBKGAttachment;
+ }
+ virtual void SetBKGColor(FX_ARGB dwBKGColor)
+ {
+ m_NonInheritedData.m_dwBKGColor = dwBKGColor;
+ }
+ virtual void SetBKGPosition(const FDE_CSSPOINT &bkgPosition)
+ {
+ m_NonInheritedData.m_BKGPosition = bkgPosition;
+ }
+ virtual FDE_CSSVISIBILITY GetVisibility() const
+ {
+ return (FDE_CSSVISIBILITY)m_InheritedData.m_eVisibility;
+ }
+ virtual FDE_CSSOVERFLOW GetOverflowX() const
+ {
+ return (FDE_CSSOVERFLOW)m_NonInheritedData.m_eOverflowX;
+ }
+ virtual FDE_CSSOVERFLOW GetOverflowY() const
+ {
+ return (FDE_CSSOVERFLOW)m_NonInheritedData.m_eOverflowY;
+ }
+ virtual FX_INT32 CountCursorUrls() const
+ {
+ return m_InheritedData.m_pCursorUris == NULL ? 0 : m_InheritedData.m_pCursorUris->CountValues();
+ }
+ virtual FX_LPCWSTR GetCursorUrl(FX_INT32 index) const
+ {
+ FXSYS_assert(m_InheritedData.m_pCursorUris != NULL);
+ return ((IFDE_CSSPrimitiveValue*)(m_InheritedData.m_pCursorUris->GetValue(index)))->GetString(index);
+ }
+ virtual FDE_CSSCURSOR GetCursorType() const
+ {
+ return m_InheritedData.m_eCursor;
+ }
+ virtual void SetVisibility(FDE_CSSVISIBILITY eVisibility)
+ {
+ m_InheritedData.m_eVisibility = eVisibility;
+ }
+ virtual FDE_CSSLISTSTYLETYPE GetListStyleType() const
+ {
+ return (FDE_CSSLISTSTYLETYPE)m_NonInheritedData.m_eListStyleType;
+ }
+ virtual FDE_CSSLISTSTYLEPOSITION GetListStylePosition() const
+ {
+ return (FDE_CSSLISTSTYLEPOSITION)m_NonInheritedData.m_eListStylePosition;
+ }
+ virtual FX_LPCWSTR GetListStyleImage() const
+ {
+ return m_InheritedData.m_pszListStyleImage;
+ }
+ virtual void SetListStyleType(FDE_CSSLISTSTYLETYPE eListStyleType)
+ {
+ m_NonInheritedData.m_eListStyleType = eListStyleType;
+ }
+ virtual void SetListStylePosition(FDE_CSSLISTSTYLEPOSITION eListStylePosition)
+ {
+ m_NonInheritedData.m_eListStylePosition = eListStylePosition;
+ }
+ void AddCustomStyle(const CFX_WideString &wsName, const CFX_WideString &wsValue)
+ {
+ m_CustomProperties.Add(wsName);
+ m_CustomProperties.Add(wsValue);
+ }
+ FX_DWORD m_dwRefCount;
+ IFX_MEMAllocator *m_pAllocator;
+ CFDE_CSSInheritedData m_InheritedData;
+ CFDE_CSSNonInheritedData m_NonInheritedData;
+ CFX_WideStringArray m_CustomProperties;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_cssstylesheet.cpp b/xfa/src/fdp/src/css/fde_cssstylesheet.cpp
new file mode 100644
index 0000000000..19bef6632c
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssstylesheet.cpp
@@ -0,0 +1,481 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_csssyntax.h"
+#include "fde_cssdatatable.h"
+#include "fde_cssstylesheet.h"
+IFDE_CSSStyleSheet* IFDE_CSSStyleSheet::LoadHTMLStandardStyleSheet()
+{
+ static const FX_LPCWSTR s_pStyle = (FX_LPCWSTR)L"html,address,blockquote,body,dd,div,dl,dt,fieldset,form,frame,frameset,h1,h2,h3,h4,h5,h6,noframes,ol,p,ul,center,dir,hr,menu,pre{display:block}"
+ L"li{display:list-item}head{display:none}table{display:table}tr{display:table-row}thead{display:table-header-group}tbody{display:table-row-group}tfoot{display:table-footer-group}"
+ L"col{display:table-column}colgroup{display:table-column-group}td,th{display:table-cell}caption{display:table-caption}th{font-weight:bolder;text-align:center}caption{text-align:center}"
+ L"body{margin:0}h1{font-size:2em;margin:.67em 0}h2{font-size:1.5em;margin:.75em 0}h3{font-size:1.17em;margin:.83em 0}h4,p,blockquote,ul,fieldset,form,ol,dl,dir,menu{margin:1.12em 0}"
+ L"h5{font-size:.83em;margin:1.5em 0}h6{font-size:.75em;margin:1.67em 0}h1,h2,h3,h4,h5,h6,b,strong{font-weight:bolder}blockquote{margin-left:40px;margin-right:40px}i,cite,em,var,address{font-style:italic}"
+ L"pre,tt,code,kbd,samp{font-family:monospace}pre{white-space:pre}button,textarea,input,select{display:inline-block}big{font-size:1.17em}small,sub,sup{font-size:.83em}sub{vertical-align:sub}"
+ L"sup{vertical-align:super}table{border-spacing:2px}thead,tbody,tfoot{vertical-align:middle}td,th,tr{vertical-align:inherit}s,strike,del{text-decoration:line-through}hr{border:1px inset silver}"
+ L"ol,ul,dir,menu,dd{margin-left:40px}ol{list-style-type:decimal}ol ul,ul ol,ul ul,ol ol{margin-top:0;margin-bottom:0}u,ins{text-decoration:underline}center{text-align:center}"
+ L"ruby{display:ruby}rt{display:ruby-text;font-size:.5em}rb{display:ruby-base}rbc{display:ruby-base-group}rtc{display:ruby-text-group}"
+ L"q:before{content:open-quote}q:after{content:close-quote}"
+ L"rp{display:none}";
+ return IFDE_CSSStyleSheet::LoadFromBuffer(CFX_WideString(), s_pStyle, FXSYS_wcslen(s_pStyle), FX_CODEPAGE_UTF8);
+}
+IFDE_CSSStyleSheet* IFDE_CSSStyleSheet::LoadFromStream(const CFX_WideString &szUrl, IFX_Stream *pStream, FX_WORD wCodePage, FX_DWORD dwMediaList )
+{
+ CFDE_CSSStyleSheet *pStyleSheet = FDE_New CFDE_CSSStyleSheet(dwMediaList);
+ if (pStyleSheet == NULL) {
+ return NULL;
+ }
+ if (!pStyleSheet->LoadFromStream(szUrl, pStream, wCodePage)) {
+ pStyleSheet->Release();
+ pStyleSheet = NULL;
+ }
+ return pStyleSheet;
+}
+IFDE_CSSStyleSheet* IFDE_CSSStyleSheet::LoadFromBuffer(const CFX_WideString &szUrl, FX_LPCWSTR pBuffer, FX_INT32 iBufSize, FX_WORD wCodePage, FX_DWORD dwMediaList )
+{
+ CFDE_CSSStyleSheet *pStyleSheet = FDE_New CFDE_CSSStyleSheet(dwMediaList);
+ if (pStyleSheet == NULL) {
+ return NULL;
+ }
+ if (!pStyleSheet->LoadFromBuffer(szUrl, pBuffer, iBufSize, wCodePage)) {
+ pStyleSheet->Release();
+ pStyleSheet = NULL;
+ }
+ return pStyleSheet;
+}
+CFDE_CSSStyleSheet::CFDE_CSSStyleSheet(FX_DWORD dwMediaList)
+ : m_wCodePage(FX_CODEPAGE_UTF8)
+ , m_wRefCount(1)
+ , m_dwMediaList(dwMediaList)
+ , m_pAllocator(NULL)
+{
+ FXSYS_assert(m_dwMediaList > 0);
+}
+CFDE_CSSStyleSheet::~CFDE_CSSStyleSheet()
+{
+ Reset();
+}
+void CFDE_CSSStyleSheet::Reset()
+{
+ for (FX_INT32 i = m_RuleArray.GetSize() - 1; i >= 0; --i) {
+ IFDE_CSSRule *pRule = m_RuleArray.GetAt(i);
+ switch (pRule->GetType()) {
+ case FDE_CSSRULETYPE_Style:
+ ((CFDE_CSSStyleRule*)pRule)->~CFDE_CSSStyleRule();
+ break;
+ case FDE_CSSRULETYPE_Media:
+ ((CFDE_CSSMediaRule*)pRule)->~CFDE_CSSMediaRule();
+ break;
+ case FDE_CSSRULETYPE_FontFace:
+ ((CFDE_CSSFontFaceRule*)pRule)->~CFDE_CSSFontFaceRule();
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ }
+ m_RuleArray.RemoveAll();
+ m_Selectors.RemoveAll();
+ m_StringCache.RemoveAll();
+ if (m_pAllocator) {
+ m_pAllocator->Release();
+ m_pAllocator = NULL;
+ }
+}
+FX_DWORD CFDE_CSSStyleSheet::AddRef()
+{
+ return ++m_wRefCount;
+}
+FX_DWORD CFDE_CSSStyleSheet::Release()
+{
+ FX_DWORD dwRefCount = --m_wRefCount;
+ if (dwRefCount == 0) {
+ FDE_Delete this;
+ }
+ return dwRefCount;
+}
+FX_INT32 CFDE_CSSStyleSheet::CountRules() const
+{
+ return m_RuleArray.GetSize();
+}
+IFDE_CSSRule* CFDE_CSSStyleSheet::GetRule(FX_INT32 index)
+{
+ return m_RuleArray.GetAt(index);
+}
+FX_BOOL CFDE_CSSStyleSheet::LoadFromStream(const CFX_WideString &szUrl, IFX_Stream *pStream, FX_WORD wCodePage)
+{
+ FXSYS_assert(pStream != NULL);
+ IFDE_CSSSyntaxParser *pSyntax = IFDE_CSSSyntaxParser::Create();
+ if (pSyntax == NULL) {
+ return FALSE;
+ }
+ if (pStream->GetCodePage() != wCodePage) {
+ pStream->SetCodePage(wCodePage);
+ }
+ FX_BOOL bRet = pSyntax->Init(pStream, 4096) && LoadFromSyntax(pSyntax);
+ pSyntax->Release();
+ m_wCodePage = wCodePage;
+ m_szUrl = szUrl;
+ return bRet;
+}
+FX_BOOL CFDE_CSSStyleSheet::LoadFromBuffer(const CFX_WideString &szUrl, FX_LPCWSTR pBuffer, FX_INT32 iBufSize, FX_WORD wCodePage)
+{
+ FXSYS_assert(pBuffer != NULL && iBufSize > 0);
+ IFDE_CSSSyntaxParser *pSyntax = IFDE_CSSSyntaxParser::Create();
+ if (pSyntax == NULL) {
+ return FALSE;
+ }
+ FX_BOOL bRet = pSyntax->Init(pBuffer, iBufSize) && LoadFromSyntax(pSyntax);
+ pSyntax->Release();
+ m_wCodePage = wCodePage;
+ m_szUrl = szUrl;
+ return bRet;
+}
+FX_BOOL CFDE_CSSStyleSheet::LoadFromSyntax(IFDE_CSSSyntaxParser *pSyntax)
+{
+ Reset();
+ m_pAllocator = FX_CreateAllocator(FX_ALLOCTYPE_Static, 1024, 0);
+ if (m_pAllocator == NULL) {
+ return FALSE;
+ }
+ FDE_CSSSYNTAXSTATUS eStatus;
+ do {
+ switch (eStatus = pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_StyleRule:
+ eStatus = LoadStyleRule(pSyntax, m_RuleArray);
+ break;
+ case FDE_CSSSYNTAXSTATUS_MediaRule:
+ eStatus = LoadMediaRule(pSyntax);
+ break;
+ case FDE_CSSSYNTAXSTATUS_FontFaceRule:
+ eStatus = LoadFontFaceRule(pSyntax, m_RuleArray);
+ break;
+ case FDE_CSSSYNTAXSTATUS_ImportRule:
+ eStatus = LoadImportRule(pSyntax);
+ break;
+ case FDE_CSSSYNTAXSTATUS_PageRule:
+ eStatus = LoadPageRule(pSyntax);
+ break;
+ default:
+ break;
+ }
+ } while (eStatus >= FDE_CSSSYNTAXSTATUS_None);
+ m_Selectors.RemoveAll();
+ m_StringCache.RemoveAll();
+ return eStatus != FDE_CSSSYNTAXSTATUS_Error;
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadMediaRule(IFDE_CSSSyntaxParser *pSyntax)
+{
+ FX_DWORD dwMediaList = 0;
+ CFDE_CSSMediaRule *pMediaRule = NULL;
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_MediaType: {
+ FX_INT32 iLen;
+ FX_LPCWSTR psz = pSyntax->GetCurrentString(iLen);
+ FDE_LPCCSSMEDIATYPETABLE pMediaType = FDE_GetCSSMediaTypeByName(psz, iLen);
+ if (pMediaType != NULL) {
+ dwMediaList |= pMediaType->wValue;
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_StyleRule:
+ if (pMediaRule == NULL) {
+ SkipRuleSet(pSyntax);
+ } else {
+ FDE_CSSSYNTAXSTATUS eStatus = LoadStyleRule(pSyntax, pMediaRule->GetArray());
+ if (eStatus < FDE_CSSSYNTAXSTATUS_None) {
+ return eStatus;
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclOpen:
+ if ((dwMediaList & m_dwMediaList) > 0 && pMediaRule == NULL) {
+ pMediaRule = FDE_NewWith(m_pAllocator) CFDE_CSSMediaRule(dwMediaList);
+ m_RuleArray.Add(pMediaRule);
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclClose:
+ return FDE_CSSSYNTAXSTATUS_None;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadStyleRule(IFDE_CSSSyntaxParser *pSyntax, CFDE_CSSRuleArray &ruleArray)
+{
+ m_Selectors.RemoveAt(0, m_Selectors.GetSize());
+ CFDE_CSSStyleRule *pStyleRule = NULL;
+ FX_LPCWSTR pszValue = NULL;
+ FX_INT32 iValueLen = 0;
+ FDE_CSSPROPERTYARGS propertyArgs;
+ propertyArgs.pStaticStore = m_pAllocator;
+ propertyArgs.pStringCache = &m_StringCache;
+ propertyArgs.pProperty = NULL;
+ CFX_WideString wsName;
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_Selector: {
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ IFDE_CSSSelector *pSelector = CFDE_CSSSelector::FromString(m_pAllocator, pszValue, iValueLen);
+ if (pSelector != NULL) {
+ m_Selectors.Add(pSelector);
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_PropertyName:
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ propertyArgs.pProperty = FDE_GetCSSPropertyByName(pszValue, iValueLen);
+ if (propertyArgs.pProperty == NULL) {
+ wsName = CFX_WideStringC(pszValue, iValueLen);
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_PropertyValue:
+ if (propertyArgs.pProperty != NULL) {
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ if (iValueLen > 0) {
+ pStyleRule->GetDeclImp().AddProperty(&propertyArgs, pszValue, iValueLen);
+ }
+ } else if (iValueLen > 0) {
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ if (iValueLen > 0) {
+ pStyleRule->GetDeclImp().AddProperty(&propertyArgs, wsName, wsName.GetLength(), pszValue, iValueLen);
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclOpen:
+ if (pStyleRule == NULL && m_Selectors.GetSize() > 0) {
+ pStyleRule = FDE_NewWith(m_pAllocator) CFDE_CSSStyleRule;
+ pStyleRule->SetSelector(m_pAllocator, m_Selectors);
+ ruleArray.Add(pStyleRule);
+ } else {
+ SkipRuleSet(pSyntax);
+ return FDE_CSSSYNTAXSTATUS_None;
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclClose:
+ if (pStyleRule != NULL && pStyleRule->GetDeclImp().GetStartPosition() == NULL) {
+ pStyleRule->~CFDE_CSSStyleRule();
+ ruleArray.RemoveLast(1);
+ }
+ return FDE_CSSSYNTAXSTATUS_None;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadFontFaceRule(IFDE_CSSSyntaxParser *pSyntax, CFDE_CSSRuleArray &ruleArray)
+{
+ CFDE_CSSFontFaceRule *pFontFaceRule = NULL;
+ FX_LPCWSTR pszValue = NULL;
+ FX_INT32 iValueLen = 0;
+ FDE_CSSPROPERTYARGS propertyArgs;
+ propertyArgs.pStaticStore = m_pAllocator;
+ propertyArgs.pStringCache = &m_StringCache;
+ propertyArgs.pProperty = NULL;
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_PropertyName:
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ propertyArgs.pProperty = FDE_GetCSSPropertyByName(pszValue, iValueLen);
+ break;
+ case FDE_CSSSYNTAXSTATUS_PropertyValue:
+ if (propertyArgs.pProperty != NULL) {
+ pszValue = pSyntax->GetCurrentString(iValueLen);
+ if (iValueLen > 0) {
+ pFontFaceRule->GetDeclImp().AddProperty(&propertyArgs, pszValue, iValueLen);
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclOpen:
+ if (pFontFaceRule == NULL) {
+ pFontFaceRule = FDE_NewWith(m_pAllocator) CFDE_CSSFontFaceRule;
+ ruleArray.Add(pFontFaceRule);
+ }
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclClose:
+ return FDE_CSSSYNTAXSTATUS_None;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+ return FDE_CSSSYNTAXSTATUS_None;
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadImportRule(IFDE_CSSSyntaxParser *pSyntax)
+{
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_ImportClose:
+ return FDE_CSSSYNTAXSTATUS_None;
+ case FDE_CSSSYNTAXSTATUS_URI:
+ break;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::LoadPageRule(IFDE_CSSSyntaxParser *pSyntax)
+{
+ return SkipRuleSet(pSyntax);
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSStyleSheet::SkipRuleSet(IFDE_CSSSyntaxParser *pSyntax)
+{
+ for (;;) {
+ switch (pSyntax->DoSyntaxParse()) {
+ case FDE_CSSSYNTAXSTATUS_Selector:
+ case FDE_CSSSYNTAXSTATUS_DeclOpen:
+ case FDE_CSSSYNTAXSTATUS_PropertyName:
+ case FDE_CSSSYNTAXSTATUS_PropertyValue:
+ break;
+ case FDE_CSSSYNTAXSTATUS_DeclClose:
+ return FDE_CSSSYNTAXSTATUS_None;
+ FDE_CSSSWITCHDEFAULTS();
+ }
+ }
+ return FDE_CSSSYNTAXSTATUS_None;
+}
+void CFDE_CSSStyleRule::SetSelector(IFX_MEMAllocator *pStaticStore, const CFDE_CSSSelectorArray &list)
+{
+ FXSYS_assert(m_ppSelector == NULL);
+ m_iSelectors = list.GetSize();
+ m_ppSelector = (IFDE_CSSSelector**)pStaticStore->Alloc(m_iSelectors * sizeof(IFDE_CSSSelector*));
+ for (FX_INT32 i = 0; i < m_iSelectors; ++i) {
+ m_ppSelector[i] = list.GetAt(i);
+ }
+}
+CFDE_CSSMediaRule::~CFDE_CSSMediaRule()
+{
+ for (FX_INT32 i = m_RuleArray.GetSize() - 1; i >= 0; --i) {
+ IFDE_CSSRule *pRule = m_RuleArray.GetAt(i);
+ switch (pRule->GetType()) {
+ case FDE_CSSRULETYPE_Style:
+ ((CFDE_CSSStyleRule*)pRule)->~CFDE_CSSStyleRule();
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ }
+}
+inline FX_BOOL FDE_IsCSSChar(FX_WCHAR wch)
+{
+ return (wch >= 'a' && wch <= 'z') || (wch >= 'A' && wch <= 'Z');
+}
+FX_INT32 FDE_GetCSSPersudoLen(FX_LPCWSTR psz, FX_LPCWSTR pEnd)
+{
+ FXSYS_assert(*psz == ':');
+ FX_LPCWSTR pStart = psz;
+ while (psz < pEnd) {
+ FX_WCHAR wch = *psz;
+ if (FDE_IsCSSChar(wch) || wch == ':') {
+ ++psz;
+ } else {
+ break;
+ }
+ }
+ return psz - pStart;
+}
+FX_INT32 FDE_GetCSSNameLen(FX_LPCWSTR psz, FX_LPCWSTR pEnd)
+{
+ FX_LPCWSTR pStart = psz;
+ while (psz < pEnd) {
+ FX_WCHAR wch = *psz;
+ if (FDE_IsCSSChar(wch)
+ || (wch >= '0' && wch <= '9')
+ || wch == '_' || wch == '-') {
+ ++psz;
+ } else {
+ break;
+ }
+ }
+ return psz - pStart;
+}
+IFDE_CSSSelector* CFDE_CSSSelector::FromString(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR psz, FX_INT32 iLen)
+{
+ FXSYS_assert(pStaticStore != NULL && psz != NULL && iLen > 0);
+ FX_LPCWSTR pStart = psz;
+ FX_LPCWSTR pEnd = psz + iLen;
+ for (; psz < pEnd; ++psz) {
+ switch (*psz) {
+ case '>':
+ case '[':
+ case '+':
+ return NULL;
+ }
+ }
+ CFDE_CSSSelector *pFirst = NULL, *pLast = NULL;
+ CFDE_CSSSelector *pPersudoFirst = NULL, *pPersudoLast = NULL;
+ for (psz = pStart ; psz < pEnd; ) {
+ FX_WCHAR wch = *psz;
+ if (wch == '.' || wch == '#') {
+ if (psz == pStart || psz[-1] == ' ') {
+ CFDE_CSSSelector *p = FDE_NewWith(pStaticStore) CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Element, (FX_LPCWSTR)L"*", 1, TRUE);
+ if (p == NULL) {
+ return NULL;
+ }
+ if (pFirst != NULL) {
+ pFirst->SetType(FDE_CSSSELECTORTYPE_Descendant);
+ p->SetNext(pFirst);
+ }
+ pFirst = pLast = p;
+ }
+ FXSYS_assert(pLast != NULL);
+ FX_INT32 iNameLen = FDE_GetCSSNameLen(++psz, pEnd);
+ if (iNameLen == 0) {
+ return NULL;
+ }
+ FDE_CSSSELECTORTYPE eType = wch == '.' ? FDE_CSSSELECTORTYPE_Class : FDE_CSSSELECTORTYPE_ID;
+ CFDE_CSSSelector *p = FDE_NewWith(pStaticStore) CFDE_CSSSelector(eType, psz, iNameLen, FALSE);
+ if (p == NULL) {
+ return NULL;
+ }
+ p->SetNext(pLast->GetNextSelector());
+ pLast->SetNext(p);
+ pLast = p;
+ psz += iNameLen;
+ } else if (FDE_IsCSSChar(wch) || wch == '*') {
+ FX_INT32 iNameLen = wch == '*' ? 1 : FDE_GetCSSNameLen(psz, pEnd);
+ if (iNameLen == 0) {
+ return NULL;
+ }
+ CFDE_CSSSelector *p = FDE_NewWith(pStaticStore) CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Element, psz, iNameLen, TRUE);
+ if (p == NULL) {
+ return NULL;
+ }
+ if (pFirst == NULL) {
+ pFirst = pLast = p;
+ } else {
+ pFirst->SetType(FDE_CSSSELECTORTYPE_Descendant);
+ p->SetNext(pFirst);
+ pFirst = pLast = p;
+ }
+ psz += iNameLen;
+ } else if (wch == ':') {
+ FX_INT32 iNameLen = FDE_GetCSSPersudoLen(psz, pEnd);
+ if (iNameLen == 0) {
+ return NULL;
+ }
+ CFDE_CSSSelector *p = FDE_NewWith(pStaticStore) CFDE_CSSSelector(FDE_CSSSELECTORTYPE_Persudo, psz, iNameLen, TRUE);
+ if (p == NULL) {
+ return NULL;
+ }
+ if (pPersudoFirst == NULL) {
+ pPersudoFirst = pPersudoLast = p;
+ } else {
+ pPersudoLast->SetNext(p);
+ pPersudoLast = p;
+ }
+ psz += iNameLen;
+ } else if (wch == ' ') {
+ psz++;
+ } else {
+ return NULL;
+ }
+ }
+ if (pPersudoFirst == NULL) {
+ return pFirst;
+ } else {
+ pPersudoLast->SetNext(pFirst);
+ return pPersudoFirst;
+ }
+}
diff --git a/xfa/src/fdp/src/css/fde_cssstylesheet.h b/xfa/src/fdp/src/css/fde_cssstylesheet.h
new file mode 100644
index 0000000000..04251a0c6b
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_cssstylesheet.h
@@ -0,0 +1,163 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSSTYLESHEET
+#define _FDE_CSSSTYLESHEET
+#include "fde_cssdeclaration.h"
+class CFDE_CSSSelector : public IFDE_CSSSelector, public CFX_Target
+{
+public:
+ CFDE_CSSSelector(FDE_CSSSELECTORTYPE eType, FX_LPCWSTR psz, FX_INT32 iLen, FX_BOOL bIgnoreCase)
+ : m_eType(eType), m_dwHash(FX_HashCode_String_GetW(psz, iLen, bIgnoreCase)), m_pNext(NULL)
+ {
+ }
+ virtual FDE_CSSSELECTORTYPE GetType() const
+ {
+ return m_eType;
+ }
+
+ virtual FX_DWORD GetNameHash() const
+ {
+ return m_dwHash;
+ }
+
+ virtual IFDE_CSSSelector* GetNextSelector() const
+ {
+ return m_pNext;
+ }
+ static IFDE_CSSSelector* FromString(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR psz, FX_INT32 iLen);
+ void SetNext(IFDE_CSSSelector *pNext)
+ {
+ m_pNext = pNext;
+ }
+protected:
+ static CFDE_CSSSelector* ParseSelector(IFX_MEMAllocator *pStaticStore, FX_LPCWSTR psz, FX_INT32 &iOff, FX_INT32 iLen, FDE_CSSSELECTORTYPE eType);
+ void SetType(FDE_CSSSELECTORTYPE eType)
+ {
+ m_eType = eType;
+ }
+ FDE_CSSSELECTORTYPE m_eType;
+ FX_DWORD m_dwHash;
+ IFDE_CSSSelector *m_pNext;
+};
+typedef CFX_ArrayTemplate<IFDE_CSSSelector*> CFDE_CSSSelectorArray;
+class CFDE_CSSStyleRule : public IFDE_CSSStyleRule, public CFX_Target
+{
+public:
+ CFDE_CSSStyleRule() : m_ppSelector(NULL), m_iSelectors(0) { }
+ virtual FX_INT32 CountSelectorLists() const
+ {
+ return m_iSelectors;
+ }
+ virtual IFDE_CSSSelector* GetSelectorList(FX_INT32 index) const
+ {
+ return m_ppSelector[index];
+ }
+
+ virtual IFDE_CSSDeclaration* GetDeclaration() const
+ {
+ return (IFDE_CSSDeclaration*)&m_Declaration;
+ }
+ CFDE_CSSDeclaration& GetDeclImp()
+ {
+ return m_Declaration;
+ }
+ void SetSelector(IFX_MEMAllocator *pStaticStore, const CFDE_CSSSelectorArray &list);
+protected:
+ CFDE_CSSDeclaration m_Declaration;
+ IFDE_CSSSelector **m_ppSelector;
+ FX_INT32 m_iSelectors;
+};
+class CFDE_CSSMediaRule : public IFDE_CSSMediaRule, public CFX_Target
+{
+public:
+ CFDE_CSSMediaRule(FX_DWORD dwMediaList) : m_dwMediaList(dwMediaList) { }
+ ~CFDE_CSSMediaRule();
+
+ virtual FX_DWORD GetMediaList() const
+ {
+ return m_dwMediaList;
+ }
+
+ virtual FX_INT32 CountRules() const
+ {
+ return m_RuleArray.GetSize();
+ }
+ virtual IFDE_CSSRule* GetRule(FX_INT32 index)
+ {
+ return m_RuleArray.GetAt(index);
+ }
+ CFDE_CSSRuleArray& GetArray()
+ {
+ return m_RuleArray;
+ }
+protected:
+ FX_DWORD m_dwMediaList;
+ CFDE_CSSRuleArray m_RuleArray;
+};
+class CFDE_CSSFontFaceRule : public IFDE_CSSFontFaceRule, public CFX_Target
+{
+public:
+ virtual IFDE_CSSDeclaration* GetDeclaration() const
+ {
+ return (IFDE_CSSDeclaration*)&m_Declaration;
+ }
+ CFDE_CSSDeclaration& GetDeclImp()
+ {
+ return m_Declaration;
+ }
+protected:
+ CFDE_CSSDeclaration m_Declaration;
+};
+#define FDE_CSSSWITCHDEFAULTS() case FDE_CSSSYNTAXSTATUS_EOS: \
+ return FDE_CSSSYNTAXSTATUS_EOS; \
+ case FDE_CSSSYNTAXSTATUS_Error: \
+ default: \
+ return FDE_CSSSYNTAXSTATUS_Error;
+class CFDE_CSSStyleSheet : public IFDE_CSSStyleSheet, public CFX_Target
+{
+public:
+ CFDE_CSSStyleSheet(FX_DWORD dwMediaList);
+ ~CFDE_CSSStyleSheet();
+ virtual FX_DWORD AddRef();
+ virtual FX_DWORD Release();
+
+ virtual FX_BOOL GetUrl(CFX_WideString &szUrl)
+ {
+ szUrl = m_szUrl;
+ return szUrl.GetLength() > 0;
+ }
+ virtual FX_DWORD GetMediaList() const
+ {
+ return m_dwMediaList;
+ }
+ virtual FX_WORD GetCodePage() const
+ {
+ return m_wCodePage;
+ }
+ virtual FX_INT32 CountRules() const;
+ virtual IFDE_CSSRule* GetRule(FX_INT32 index);
+ FX_BOOL LoadFromStream(const CFX_WideString &szUrl, IFX_Stream *pStream, FX_WORD wCodePage);
+ FX_BOOL LoadFromBuffer(const CFX_WideString &szUrl, FX_LPCWSTR pBuffer, FX_INT32 iBufSize, FX_WORD wCodePage);
+protected:
+ void Reset();
+ FX_BOOL LoadFromSyntax(IFDE_CSSSyntaxParser *pSyntax);
+ FDE_CSSSYNTAXSTATUS LoadStyleRule(IFDE_CSSSyntaxParser *pSyntax, CFDE_CSSRuleArray &ruleArray);
+ FDE_CSSSYNTAXSTATUS LoadImportRule(IFDE_CSSSyntaxParser *pSyntax);
+ FDE_CSSSYNTAXSTATUS LoadPageRule(IFDE_CSSSyntaxParser *pSyntax);
+ FDE_CSSSYNTAXSTATUS LoadMediaRule(IFDE_CSSSyntaxParser *pSyntax);
+ FDE_CSSSYNTAXSTATUS LoadFontFaceRule(IFDE_CSSSyntaxParser *pSyntax, CFDE_CSSRuleArray &ruleArray);
+ FDE_CSSSYNTAXSTATUS SkipRuleSet(IFDE_CSSSyntaxParser *pSyntax);
+ FX_WORD m_wCodePage;
+ FX_WORD m_wRefCount;
+ FX_DWORD m_dwMediaList;
+ IFX_MEMAllocator *m_pAllocator;
+ CFDE_CSSRuleArray m_RuleArray;
+ CFX_WideString m_szUrl;
+ CFDE_CSSSelectorArray m_Selectors;
+ CFX_MapPtrToPtr m_StringCache;
+};
+#endif
diff --git a/xfa/src/fdp/src/css/fde_csssyntax.cpp b/xfa/src/fdp/src/css/fde_csssyntax.cpp
new file mode 100644
index 0000000000..b7e5da9d6c
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_csssyntax.cpp
@@ -0,0 +1,495 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_csssyntax.h"
+#include "fde_cssdatatable.h"
+#ifdef _cplusplus
+extern "C" {
+#endif
+ inline FX_BOOL FDE_IsSelectorStart(FX_WCHAR wch)
+ {
+ return wch == '.' || wch == '#' || wch == '*'
+ || (wch >= 'a' && wch <= 'z')
+ || (wch >= 'A' && wch <= 'Z');
+ }
+#ifdef _cplusplus
+};
+#endif
+IFDE_CSSSyntaxParser* IFDE_CSSSyntaxParser::Create()
+{
+ return FDE_New CFDE_CSSSyntaxParser;
+}
+CFDE_CSSSyntaxParser::CFDE_CSSSyntaxParser()
+ : m_pStream(NULL)
+ , m_iStreamPos(0)
+ , m_iPlaneSize(0)
+ , m_iTextDatLen(0)
+ , m_dwCheck((FX_DWORD) - 1)
+ , m_eMode(FDE_CSSSYNTAXMODE_RuleSet)
+ , m_eStatus(FDE_CSSSYNTAXSTATUS_None)
+{
+}
+CFDE_CSSSyntaxParser::~CFDE_CSSSyntaxParser()
+{
+ m_TextData.Reset();
+ m_TextPlane.Reset();
+}
+FX_BOOL CFDE_CSSSyntaxParser::Init(IFX_Stream *pStream, FX_INT32 iCSSPlaneSize, FX_INT32 iTextDataSize , FX_BOOL bOnlyDeclaration )
+{
+ FXSYS_assert(pStream != NULL && iCSSPlaneSize > 0 && iTextDataSize > 0);
+ Reset(bOnlyDeclaration);
+ if (!m_TextData.EstimateSize(iTextDataSize)) {
+ return FALSE;
+ }
+ FX_BYTE bom[4];
+ m_pStream = pStream;
+ m_iStreamPos = m_pStream->GetBOM(bom);
+ m_iPlaneSize = iCSSPlaneSize;
+ return TRUE;
+}
+FX_BOOL CFDE_CSSSyntaxParser::Init(FX_LPCWSTR pBuffer, FX_INT32 iBufferSize, FX_INT32 iTextDatSize , FX_BOOL bOnlyDeclaration )
+{
+ FXSYS_assert(pBuffer != NULL && iBufferSize > 0 && iTextDatSize > 0);
+ Reset(bOnlyDeclaration);
+ if (!m_TextData.EstimateSize(iTextDatSize)) {
+ return FALSE;
+ }
+ return m_TextPlane.AttachBuffer(pBuffer, iBufferSize);
+}
+void CFDE_CSSSyntaxParser::Reset(FX_BOOL bOnlyDeclaration)
+{
+ m_TextPlane.Reset();
+ m_TextData.Reset();
+ m_pStream = NULL;
+ m_iStreamPos = 0;
+ m_iTextDatLen = 0;
+ m_dwCheck = (FX_DWORD) - 1;
+ m_eStatus = FDE_CSSSYNTAXSTATUS_None;
+ m_eMode = bOnlyDeclaration ? FDE_CSSSYNTAXMODE_PropertyName : FDE_CSSSYNTAXMODE_RuleSet;
+}
+FDE_CSSSYNTAXSTATUS CFDE_CSSSyntaxParser::DoSyntaxParse()
+{
+ while (m_eStatus >= FDE_CSSSYNTAXSTATUS_None) {
+ if (m_TextPlane.IsEOF()) {
+ if (m_pStream == NULL) {
+ if (m_eMode == FDE_CSSSYNTAXMODE_PropertyValue && m_TextData.GetLength() > 0) {
+ SaveTextData();
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_PropertyValue;
+ }
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_EOS;
+ }
+ FX_BOOL bEOS;
+ FX_INT32 iLen = m_TextPlane.LoadFromStream(m_pStream, m_iStreamPos, m_iPlaneSize, bEOS);
+ m_iStreamPos = m_pStream->GetPosition();
+ if (iLen < 1) {
+ if (m_eMode == FDE_CSSSYNTAXMODE_PropertyValue && m_TextData.GetLength() > 0) {
+ SaveTextData();
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_PropertyValue;
+ }
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_EOS;
+ }
+ }
+ FX_WCHAR wch;
+ while (!m_TextPlane.IsEOF()) {
+ wch = m_TextPlane.GetChar();
+ switch (m_eMode) {
+ case FDE_CSSSYNTAXMODE_RuleSet:
+ switch (wch) {
+ case '@':
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_AtRule);
+ break;
+ case '}':
+ m_TextPlane.MoveNext();
+ if (RestoreMode()) {
+ return FDE_CSSSYNTAXSTATUS_DeclClose;
+ } else {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ break;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ m_ModeStack.Push(m_eMode);
+ SwitchMode(FDE_CSSSYNTAXMODE_Comment);
+ break;
+ }
+ default:
+ if (wch <= ' ') {
+ m_TextPlane.MoveNext();
+ } else if (FDE_IsSelectorStart(wch)) {
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector);
+ return FDE_CSSSYNTAXSTATUS_StyleRule;
+ } else {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_Selector:
+ switch (wch) {
+ case ',':
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector);
+ if (m_iTextDatLen > 0) {
+ return FDE_CSSSYNTAXSTATUS_Selector;
+ }
+ break;
+ case '{':
+ if (m_TextData.GetLength() > 0) {
+ SaveTextData();
+ return FDE_CSSSYNTAXSTATUS_Selector;
+ } else {
+ m_TextPlane.MoveNext();
+ m_ModeStack.Push(FDE_CSSSYNTAXMODE_RuleSet);
+ SwitchMode(FDE_CSSSYNTAXMODE_PropertyName);
+ return FDE_CSSSYNTAXSTATUS_DeclOpen;
+ }
+ break;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ if (SwitchToComment() > 0) {
+ return FDE_CSSSYNTAXSTATUS_Selector;
+ }
+ break;
+ }
+ default:
+ AppendChar(wch);
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_PropertyName:
+ switch (wch) {
+ case ':':
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_PropertyValue);
+ return FDE_CSSSYNTAXSTATUS_PropertyName;
+ case '}':
+ m_TextPlane.MoveNext();
+ if (RestoreMode()) {
+ return FDE_CSSSYNTAXSTATUS_DeclClose;
+ } else {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ break;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ if (SwitchToComment() > 0) {
+ return FDE_CSSSYNTAXSTATUS_PropertyName;
+ }
+ break;
+ }
+ default:
+ AppendChar(wch);
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_PropertyValue:
+ switch (wch) {
+ case ';':
+ m_TextPlane.MoveNext();
+ case '}':
+ SwitchMode(FDE_CSSSYNTAXMODE_PropertyName);
+ return FDE_CSSSYNTAXSTATUS_PropertyValue;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ if (SwitchToComment() > 0) {
+ return FDE_CSSSYNTAXSTATUS_PropertyValue;
+ }
+ break;
+ }
+ default:
+ AppendChar(wch);
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_Comment:
+ if (wch == '/' && m_TextData.GetLength() > 0
+ && m_TextData.GetAt(m_TextData.GetLength() - 1) == '*') {
+ RestoreMode();
+ } else {
+ m_TextData.AppendChar(wch);
+ }
+ m_TextPlane.MoveNext();
+ break;
+ case FDE_CSSSYNTAXMODE_MediaType:
+ switch (wch) {
+ case ',':
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_MediaType);
+ if (m_iTextDatLen > 0) {
+ return FDE_CSSSYNTAXSTATUS_MediaType;
+ }
+ break;
+ case '{': {
+ FDE_CSSSYNTAXMODE *pMode = m_ModeStack.GetTopElement();
+ if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_MediaRule) {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ if (m_TextData.GetLength() > 0) {
+ SaveTextData();
+ return FDE_CSSSYNTAXSTATUS_MediaType;
+ } else {
+ m_TextPlane.MoveNext();
+ *pMode = FDE_CSSSYNTAXMODE_RuleSet;
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet);
+ return FDE_CSSSYNTAXSTATUS_DeclOpen;
+ }
+ }
+ break;
+ case ';': {
+ FDE_CSSSYNTAXMODE *pMode = m_ModeStack.GetTopElement();
+ if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_Import) {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ if (m_TextData.GetLength() > 0) {
+ SaveTextData();
+ if (IsImportEnabled()) {
+ return FDE_CSSSYNTAXSTATUS_MediaType;
+ }
+ } else {
+ FX_BOOL bEnabled = IsImportEnabled();
+ m_TextPlane.MoveNext();
+ m_ModeStack.Pop();
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet);
+ if (bEnabled) {
+ DisableImport();
+ return FDE_CSSSYNTAXSTATUS_ImportClose;
+ }
+ }
+ }
+ break;
+ case '/':
+ if (m_TextPlane.GetNextChar() == '*') {
+ if (SwitchToComment() > 0) {
+ return FDE_CSSSYNTAXSTATUS_MediaType;
+ }
+ break;
+ }
+ default:
+ AppendChar(wch);
+ break;
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_URI: {
+ FDE_CSSSYNTAXMODE *pMode = m_ModeStack.GetTopElement();
+ if (pMode == NULL || *pMode != FDE_CSSSYNTAXMODE_Import) {
+ return m_eStatus = FDE_CSSSYNTAXSTATUS_Error;
+ }
+ if (wch <= ' ' || wch == ';') {
+ FX_INT32 iURIStart, iURILength = m_TextData.GetLength();
+ if (iURILength > 0 && FDE_ParseCSSURI(m_TextData.GetBuffer(), iURILength, iURIStart, iURILength)) {
+ m_TextData.Subtract(iURIStart, iURILength);
+ SwitchMode(FDE_CSSSYNTAXMODE_MediaType);
+ if (IsImportEnabled()) {
+ return FDE_CSSSYNTAXSTATUS_URI;
+ } else {
+ break;
+ }
+ }
+ }
+ AppendChar(wch);
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_AtRule:
+ if (wch > ' ') {
+ AppendChar(wch);
+ } else {
+ FX_INT32 iLen = m_TextData.GetLength();
+ FX_LPCWSTR psz = m_TextData.GetBuffer();
+ if (FXSYS_wcsncmp(L"charset", psz, iLen) == 0) {
+ SwitchMode(FDE_CSSSYNTAXMODE_Charset);
+ } else if (FXSYS_wcsncmp(L"import", psz, iLen) == 0) {
+ m_ModeStack.Push(FDE_CSSSYNTAXMODE_Import);
+ SwitchMode(FDE_CSSSYNTAXMODE_URI);
+ if (IsImportEnabled()) {
+ return FDE_CSSSYNTAXSTATUS_ImportRule;
+ } else {
+ break;
+ }
+ } else if (FXSYS_wcsncmp(L"media", psz, iLen) == 0) {
+ m_ModeStack.Push(FDE_CSSSYNTAXMODE_MediaRule);
+ SwitchMode(FDE_CSSSYNTAXMODE_MediaType);
+ return FDE_CSSSYNTAXSTATUS_MediaRule;
+ } else if (FXSYS_wcsncmp(L"font-face", psz, iLen) == 0) {
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector);
+ return FDE_CSSSYNTAXSTATUS_FontFaceRule;
+ } else if (FXSYS_wcsncmp(L"page", psz, iLen) == 0) {
+ SwitchMode(FDE_CSSSYNTAXMODE_Selector);
+ return FDE_CSSSYNTAXSTATUS_PageRule;
+ } else {
+ SwitchMode(FDE_CSSSYNTAXMODE_UnknownRule);
+ }
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_Charset:
+ if (wch == ';') {
+ m_TextPlane.MoveNext();
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet);
+ if (IsCharsetEnabled()) {
+ DisableCharset();
+ if (m_iTextDatLen > 0) {
+ if (m_pStream != NULL) {
+ FX_WORD wCodePage = FX_GetCodePageFormStringW(m_TextData.GetBuffer(), m_iTextDatLen);
+ if (wCodePage < 0xFFFF && m_pStream->GetCodePage() != wCodePage) {
+ m_pStream->SetCodePage(wCodePage);
+ }
+ }
+ return FDE_CSSSYNTAXSTATUS_Charset;
+ }
+ }
+ } else {
+ AppendChar(wch);
+ }
+ break;
+ case FDE_CSSSYNTAXMODE_UnknownRule:
+ if (wch == ';') {
+ SwitchMode(FDE_CSSSYNTAXMODE_RuleSet);
+ }
+ m_TextPlane.MoveNext();
+ break;
+ default:
+ FXSYS_assert(FALSE);
+ break;
+ }
+ }
+ }
+ return m_eStatus;
+}
+FX_BOOL CFDE_CSSSyntaxParser::IsImportEnabled() const
+{
+ if ((m_dwCheck & FDE_CSSSYNTAXCHECK_AllowImport) == 0) {
+ return FALSE;
+ }
+ if (m_ModeStack.GetSize() > 1) {
+ return FALSE;
+ }
+ return TRUE;
+}
+inline FX_BOOL CFDE_CSSSyntaxParser::AppendChar(FX_WCHAR wch)
+{
+ m_TextPlane.MoveNext();
+ if (m_TextData.GetLength() > 0 || wch > ' ') {
+ m_TextData.AppendChar(wch);
+ return TRUE;
+ }
+ return FALSE;
+}
+inline FX_INT32 CFDE_CSSSyntaxParser::SaveTextData()
+{
+ m_iTextDatLen = m_TextData.TrimEnd();
+ m_TextData.Clear();
+ return m_iTextDatLen;
+}
+inline void CFDE_CSSSyntaxParser::SwitchMode(FDE_CSSSYNTAXMODE eMode)
+{
+ m_eMode = eMode;
+ SaveTextData();
+}
+inline FX_INT32 CFDE_CSSSyntaxParser::SwitchToComment()
+{
+ FX_INT32 iLength = m_TextData.GetLength();
+ m_ModeStack.Push(m_eMode);
+ SwitchMode(FDE_CSSSYNTAXMODE_Comment);
+ return iLength;
+}
+inline FX_BOOL CFDE_CSSSyntaxParser::RestoreMode()
+{
+ FDE_CSSSYNTAXMODE *pMode = m_ModeStack.GetTopElement();
+ if (pMode == NULL) {
+ return FALSE;
+ }
+ SwitchMode(*pMode);
+ m_ModeStack.Pop();
+ return TRUE;
+}
+FX_LPCWSTR CFDE_CSSSyntaxParser::GetCurrentString(FX_INT32 &iLength) const
+{
+ iLength = m_iTextDatLen;
+ return m_TextData.GetBuffer();
+}
+CFDE_CSSTextBuf::CFDE_CSSTextBuf()
+ : m_bExtBuf(FALSE)
+ , m_pBuffer(NULL)
+ , m_iBufLen(0)
+ , m_iDatLen(0)
+ , m_iDatPos(0)
+{
+}
+CFDE_CSSTextBuf::~CFDE_CSSTextBuf()
+{
+ Reset();
+}
+void CFDE_CSSTextBuf::Reset()
+{
+ if (!m_bExtBuf && m_pBuffer != NULL) {
+ FDE_Free(m_pBuffer);
+ m_pBuffer = NULL;
+ }
+ m_iDatPos = m_iDatLen = m_iBufLen;
+}
+FX_BOOL CFDE_CSSTextBuf::AttachBuffer(FX_LPCWSTR pBuffer, FX_INT32 iBufLen)
+{
+ Reset();
+ m_pBuffer = (FX_LPWSTR)pBuffer;
+ m_iDatLen = m_iBufLen = iBufLen;
+ return m_bExtBuf = TRUE;
+}
+FX_BOOL CFDE_CSSTextBuf::EstimateSize(FX_INT32 iAllocSize)
+{
+ FXSYS_assert(iAllocSize > 0);
+ Clear();
+ m_bExtBuf = FALSE;
+ return ExpandBuf(iAllocSize);
+}
+FX_INT32 CFDE_CSSTextBuf::LoadFromStream(IFX_Stream *pTxtStream, FX_INT32 iStreamOffset, FX_INT32 iMaxChars, FX_BOOL &bEOS)
+{
+ FXSYS_assert(iStreamOffset >= 0 && iMaxChars > 0);
+ Clear();
+ m_bExtBuf = FALSE;
+ if (!ExpandBuf(iMaxChars)) {
+ return 0;
+ }
+ pTxtStream->Lock();
+ if (pTxtStream->GetPosition() != iStreamOffset) {
+ pTxtStream->Seek(FX_STREAMSEEK_Begin, iStreamOffset);
+ }
+ m_iDatLen = pTxtStream->ReadString(m_pBuffer, iMaxChars, bEOS);
+ pTxtStream->Unlock();
+ return m_iDatLen;
+}
+FX_BOOL CFDE_CSSTextBuf::ExpandBuf(FX_INT32 iDesiredSize)
+{
+ if (m_bExtBuf) {
+ return FALSE;
+ } else if (m_pBuffer == NULL) {
+ m_pBuffer = (FX_LPWSTR)FDE_Alloc(iDesiredSize * sizeof(FX_WCHAR));
+ } else if (m_iBufLen != iDesiredSize) {
+ m_pBuffer = (FX_LPWSTR)FDE_Realloc(m_pBuffer, iDesiredSize * sizeof(FX_WCHAR));
+ } else {
+ return TRUE;
+ }
+ if (m_pBuffer == NULL) {
+ m_iBufLen = 0;
+ return FALSE;
+ } else {
+ m_iBufLen = iDesiredSize;
+ return TRUE;
+ }
+}
+void CFDE_CSSTextBuf::Subtract(FX_INT32 iStart, FX_INT32 iLength)
+{
+ FXSYS_assert(iStart >= 0 && iLength > 0);
+ if (iLength > m_iDatLen - iStart) {
+ iLength = m_iDatLen - iStart;
+ }
+ if (iLength < 0) {
+ iLength = 0;
+ } else {
+ FXSYS_memmove(m_pBuffer, m_pBuffer + iStart, iLength * sizeof(FX_WCHAR));
+ }
+ m_iDatLen = iLength;
+}
diff --git a/xfa/src/fdp/src/css/fde_csssyntax.h b/xfa/src/fdp/src/css/fde_csssyntax.h
new file mode 100644
index 0000000000..c18e0f9717
--- /dev/null
+++ b/xfa/src/fdp/src/css/fde_csssyntax.h
@@ -0,0 +1,135 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_CSSSYNTAX
+#define _FDE_CSSSYNTAX
+class CFDE_CSSTextBuf : public CFX_Target
+{
+public:
+ CFDE_CSSTextBuf();
+ ~CFDE_CSSTextBuf();
+ FX_BOOL AttachBuffer(FX_LPCWSTR pBuffer, FX_INT32 iBufLen);
+ FX_BOOL EstimateSize(FX_INT32 iAllocSize);
+ FX_INT32 LoadFromStream(IFX_Stream *pTxtStream, FX_INT32 iStreamOffset, FX_INT32 iMaxChars, FX_BOOL &bEOS);
+ FX_BOOL AppendChar(FX_WCHAR wch)
+ {
+ if (m_iDatLen >= m_iBufLen && !ExpandBuf(m_iBufLen * 2)) {
+ return FALSE;
+ }
+ return (m_pBuffer[m_iDatLen++] = wch), TRUE;
+ }
+ void Clear()
+ {
+ m_iDatPos = m_iDatLen = 0;
+ }
+ void Reset();
+ FX_INT32 TrimEnd()
+ {
+ while (m_iDatLen > 0 && m_pBuffer[m_iDatLen - 1] <= ' ') {
+ --m_iDatLen;
+ }
+ AppendChar(0);
+ return --m_iDatLen;
+ }
+ void Subtract(FX_INT32 iStart, FX_INT32 iLength);
+ FX_BOOL IsEOF() const
+ {
+ return m_iDatPos >= m_iDatLen;
+ }
+ FX_WCHAR GetAt(FX_INT32 index) const
+ {
+ return m_pBuffer[index];
+ }
+ FX_WCHAR GetChar() const
+ {
+ return m_pBuffer[m_iDatPos];
+ }
+ FX_WCHAR GetNextChar() const
+ {
+ return (m_iDatPos + 1 >= m_iDatLen) ? 0 : m_pBuffer[m_iDatPos + 1];
+ }
+ void MoveNext()
+ {
+ m_iDatPos++;
+ }
+ FX_INT32 GetLength() const
+ {
+ return m_iDatLen;
+ }
+ FX_LPCWSTR GetBuffer() const
+ {
+ return m_pBuffer;
+ }
+protected:
+ FX_BOOL ExpandBuf(FX_INT32 iDesiredSize);
+ FX_BOOL m_bExtBuf;
+ FX_LPWSTR m_pBuffer;
+ FX_INT32 m_iBufLen;
+ FX_INT32 m_iDatLen;
+ FX_INT32 m_iDatPos;
+};
+#define FDE_CSSSYNTAXCHECK_AllowCharset 1
+#define FDE_CSSSYNTAXCHECK_AllowImport 2
+enum FDE_CSSSYNTAXMODE {
+ FDE_CSSSYNTAXMODE_RuleSet,
+ FDE_CSSSYNTAXMODE_Comment,
+ FDE_CSSSYNTAXMODE_AtRule,
+ FDE_CSSSYNTAXMODE_UnknownRule,
+ FDE_CSSSYNTAXMODE_Charset,
+ FDE_CSSSYNTAXMODE_Import,
+ FDE_CSSSYNTAXMODE_MediaRule,
+ FDE_CSSSYNTAXMODE_URI,
+ FDE_CSSSYNTAXMODE_MediaType,
+ FDE_CSSSYNTAXMODE_Selector,
+ FDE_CSSSYNTAXMODE_PropertyName,
+ FDE_CSSSYNTAXMODE_PropertyValue,
+};
+class CFDE_CSSSyntaxParser : public IFDE_CSSSyntaxParser, public CFX_Target
+{
+public:
+ CFDE_CSSSyntaxParser();
+ ~CFDE_CSSSyntaxParser();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_BOOL Init(IFX_Stream *pStream, FX_INT32 iCSSPlaneSize, FX_INT32 iTextDataSize = 32, FX_BOOL bOnlyDeclaration = FALSE);
+ virtual FX_BOOL Init(FX_LPCWSTR pBuffer, FX_INT32 iBufferSize, FX_INT32 iTextDatSize = 32, FX_BOOL bOnlyDeclaration = FALSE);
+ virtual FDE_CSSSYNTAXSTATUS DoSyntaxParse();
+ virtual FX_LPCWSTR GetCurrentString(FX_INT32 &iLength) const;
+protected:
+ void Reset(FX_BOOL bOnlyDeclaration);
+ void SwitchMode(FDE_CSSSYNTAXMODE eMode);
+ FX_INT32 SwitchToComment();
+
+ FX_BOOL RestoreMode();
+ FX_BOOL AppendChar(FX_WCHAR wch);
+ FX_INT32 SaveTextData();
+ FX_BOOL IsCharsetEnabled() const
+ {
+ return (m_dwCheck & FDE_CSSSYNTAXCHECK_AllowCharset) != 0;
+ }
+ void DisableCharset()
+ {
+ m_dwCheck = FDE_CSSSYNTAXCHECK_AllowImport;
+ }
+ FX_BOOL IsImportEnabled() const;
+ void DisableImport()
+ {
+ m_dwCheck = 0;
+ }
+ IFX_Stream *m_pStream;
+ FX_INT32 m_iStreamPos;
+ FX_INT32 m_iPlaneSize;
+ CFDE_CSSTextBuf m_TextData;
+ CFDE_CSSTextBuf m_TextPlane;
+ FX_INT32 m_iTextDatLen;
+ FX_DWORD m_dwCheck;
+ FDE_CSSSYNTAXMODE m_eMode;
+ FDE_CSSSYNTAXSTATUS m_eStatus;
+ CFX_StackTemplate<FDE_CSSSYNTAXMODE> m_ModeStack;
+};
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_devbasic.cpp b/xfa/src/fdp/src/fde/fde_devbasic.cpp
new file mode 100644
index 0000000000..780f1188c8
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_devbasic.cpp
@@ -0,0 +1,70 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_devbasic.h"
+static const FDE_HATCHDATA gs_HatchBitmapData[FDE_HATCHSTYLE_Total] = {
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,}},
+ {16, 16, {0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x15, 0x15, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,}},
+ {16, 16, {0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xbb, 0xbb, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,}},
+ {16, 16, {0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00,}},
+ {16, 16, {0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xdd, 0xdd, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,}},
+ {16, 16, {0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xef, 0xef, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xf7, 0xf7, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x7f, 0x7f, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00,}},
+ {16, 16, {0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,}},
+ {16, 16, {0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x33, 0x33, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0xc1, 0xc1, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00,}},
+ {16, 16, {0x83, 0x83, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00, 0x83, 0x83, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x0e, 0x0e, 0x00, 0x00, 0x1c, 0x1c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x70, 0x70, 0x00, 0x00, 0xe0, 0xe0, 0x00, 0x00, 0xc1, 0xc1, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00,}},
+ {16, 16, {0xb1, 0xb1, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x8d, 0x8d, 0x00, 0x00, 0xb1, 0xb1, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0xd8, 0xd8, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x8d, 0x8d, 0x00, 0x00,}},
+ {16, 16, {0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x25, 0x25, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00,}},
+ {16, 16, {0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x24, 0x24, 0x00, 0x00, 0x42, 0x42, 0x00, 0x00, 0x81, 0x81, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00,}},
+ {16, 16, {0x88, 0x88, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x45, 0x45, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x54, 0x54, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x45, 0x45, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x14, 0x14, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x51, 0x51, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,}},
+ {16, 16, {0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,}},
+ {16, 16, {0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+ {16, 16, {0x03, 0x03, 0x00, 0x00, 0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x84, 0x84, 0x00, 0x00, 0x48, 0x48, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0x77, 0x77, 0x00, 0x00, 0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x89, 0x89, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x8f, 0x8f, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x98, 0x98, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00, 0xf8, 0xf8, 0x00, 0x00,}},
+ {16, 16, {0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00, 0x88, 0x88, 0x00, 0x00,}},
+ {16, 16, {0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x99, 0x99, 0x00, 0x00,}},
+ {16, 16, {0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00,}},
+ {16, 16, {0x82, 0x82, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x28, 0x28, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x82, 0x82, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,}},
+ {16, 16, {0x10, 0x10, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x7c, 0x7c, 0x00, 0x00, 0x38, 0x38, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}},
+};
+FDE_LPCHATCHDATA FDE_DEVGetHatchData(FX_INT32 iHatchStyle)
+{
+ if (iHatchStyle < FDE_HATCHSTYLE_Min || iHatchStyle > FDE_HATCHSTYLE_Max) {
+ return NULL;
+ }
+ return &gs_HatchBitmapData[iHatchStyle];
+}
diff --git a/xfa/src/fdp/src/fde/fde_devbasic.h b/xfa/src/fdp/src/fde/fde_devbasic.h
new file mode 100644
index 0000000000..36d2471b2c
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_devbasic.h
@@ -0,0 +1,16 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_DEVICE_BASIC_IMP
+#define _FDE_DEVICE_BASIC_IMP
+struct FDE_HATCHDATA {
+ FX_INT32 iWidth;
+ FX_INT32 iHeight;
+ FX_BYTE MaskBits[64];
+};
+typedef FDE_HATCHDATA const * FDE_LPCHATCHDATA;
+FDE_LPCHATCHDATA FDE_DEVGetHatchData(FX_INT32 iHatchStyle);
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_gdidevice.cpp b/xfa/src/fdp/src/fde/fde_gdidevice.cpp
new file mode 100644
index 0000000000..ad7f6cc9e5
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_gdidevice.cpp
@@ -0,0 +1,555 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "stdafx.h"
+#include "fde_gdidevice.h"
+#include "fde_gdiobject.h"
+#ifdef _FDEPLUS
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_DIBitmap *pBitmap, FX_BOOL bRgbByteOrder )
+{
+ return FDE_New CFDE_GdiDevice(pBitmap);
+}
+IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_RenderDevice *pDevice)
+{
+ return NULL;
+}
+CFDE_GdiDevice::CFDE_GdiDevice(CFX_DIBitmap *pBitmap)
+ : m_dwGlyphLen(0)
+ , m_pGlyphBuf(NULL)
+ , m_pGraphics(NULL)
+ , m_pBitmap(NULL)
+ , m_pClipPath(NULL)
+{
+ FXSYS_assert(pBitmap != NULL);
+ BITMAPINFO bmi;
+ FXSYS_memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = pBitmap->GetWidth();
+ bmi.bmiHeader.biHeight = -pBitmap->GetHeight();
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
+ m_pBitmap = Gdiplus::Bitmap::FromBITMAPINFO(&bmi, pBitmap->GetBuffer());
+ FXSYS_assert(m_pBitmap != NULL);
+ m_pGraphics = Gdiplus::Graphics::FromImage(m_pBitmap);
+ FXSYS_assert(m_pGraphics != NULL);
+ m_rtClipRect.Set(0, 0, (FX_FLOAT)pBitmap->GetWidth(), (FX_FLOAT)pBitmap->GetHeight());
+ m_pGraphics->SetClip((const Gdiplus::RectF&)m_rtClipRect);
+}
+CFDE_GdiDevice::~CFDE_GdiDevice()
+{
+ delete m_pGraphics;
+ delete m_pBitmap;
+ if (m_pGlyphBuf) {
+ FDE_Free(m_pGlyphBuf);
+ }
+}
+FX_INT32 CFDE_GdiDevice::GetWidth() const
+{
+ return m_pBitmap->GetWidth();
+}
+FX_INT32 CFDE_GdiDevice::GetHeight() const
+{
+ return m_pBitmap->GetHeight();
+}
+FDE_HDEVICESTATE CFDE_GdiDevice::SaveState()
+{
+ return (FDE_HDEVICESTATE)m_pGraphics->Save();
+}
+void CFDE_GdiDevice::RestoreState(FDE_HDEVICESTATE hState)
+{
+ Gdiplus::Status eRet = m_pGraphics->Restore((Gdiplus::GraphicsState)hState);
+ if (eRet == Gdiplus::Ok) {
+ Gdiplus::Rect rt;
+ eRet = m_pGraphics->GetClipBounds(&rt);
+ if (eRet == Gdiplus::Ok) {
+ m_rtClipRect.Set((FX_FLOAT)rt.X, (FX_FLOAT)rt.Y, (FX_FLOAT)rt.Width, (FX_FLOAT)rt.Height);
+ }
+ }
+}
+FX_BOOL CFDE_GdiDevice::SetClipRect(const CFX_RectF &rtClip)
+{
+ m_rtClipRect = rtClip;
+ return m_pGraphics->SetClip((const Gdiplus::RectF&)rtClip) == Gdiplus::Ok;
+}
+const CFX_RectF& CFDE_GdiDevice::GetClipRect()
+{
+ return m_rtClipRect;
+}
+FX_BOOL CFDE_GdiDevice::SetClipPath(const IFDE_Path *pClip)
+{
+ m_pClipPath = (CFDE_GdiPath*)pClip;
+ Gdiplus::GraphicsPath *pPath = m_pClipPath ? &m_pClipPath->m_Path : NULL;
+ return m_pGraphics->SetClip(pPath) == Gdiplus::Ok;
+}
+IFDE_Path* CFDE_GdiDevice::GetClipPath() const
+{
+ return m_pClipPath;
+}
+FX_FLOAT CFDE_GdiDevice::GetDpiX() const
+{
+ return m_pGraphics->GetDpiX();
+}
+FX_FLOAT CFDE_GdiDevice::GetDpiY() const
+{
+ return m_pGraphics->GetDpiY();
+}
+FX_BOOL CFDE_GdiDevice::DrawImage(IFDE_Image *pImg, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix, const CFX_Matrix *pDevMatrix)
+{
+ CFDE_GdiImage *pGdiImg = (CFDE_GdiImage*)pImg;
+ FXSYS_assert(pGdiImg != NULL && pGdiImg->m_pImage != NULL);
+ CFX_RectF srcRect;
+ if (pSrcRect) {
+ srcRect = *pSrcRect;
+ } else {
+ srcRect.left = srcRect.top = 0;
+ srcRect.width = (FX_FLOAT)pImg->GetImageWidth();
+ srcRect.height = (FX_FLOAT)pImg->GetImageHeight();
+ }
+ CFX_Matrix matrix;
+ if (pImgMatrix) {
+ matrix = *pImgMatrix;
+ } else {
+ matrix.Reset();
+ }
+ matrix.Translate(dstRect.left, dstRect.top);
+ matrix.Scale((dstRect.width / srcRect.width), (dstRect.height / srcRect.height), TRUE);
+ if (pDevMatrix) {
+ matrix.Concat(*pDevMatrix);
+ }
+ CFX_PointF dstPoints[3];
+ dstPoints[0].Set(0, 0);
+ dstPoints[1].Set(srcRect.width, 0);
+ dstPoints[2].Set(0, srcRect.height);
+ matrix.TransformPoints(dstPoints, 3);
+ m_pGraphics->DrawImage(pGdiImg->m_pImage, (Gdiplus::PointF*)dstPoints, 3,
+ srcRect.left, srcRect.top, srcRect.width, srcRect.height,
+ Gdiplus::UnitPixel, NULL, NULL, NULL);
+ return TRUE;
+}
+FX_BOOL CFDE_GdiDevice::DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix, const CFX_Matrix *pDevMatrix)
+{
+ FXSYS_assert(pDib != NULL);
+ BITMAPINFO bmi;
+ FXSYS_memset(&bmi, 0, sizeof(BITMAPINFOHEADER));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biWidth = pDib->GetWidth();
+ bmi.bmiHeader.biHeight = pDib->GetHeight();
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = pDib->GetBPP();
+ Gdiplus::Bitmap bmp(&bmi, pDib->GetBuffer());
+ CFDE_GdiImage img(&bmp);
+ return DrawImage(&img, pSrcRect, dstRect, pImgMatrix, pDevMatrix);
+}
+FX_BOOL CFDE_GdiDevice::DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pBrush != NULL && pFont != NULL && pCharPos != NULL);
+ FX_ARGB argb = 0xFF000000;
+ if (pBrush->GetType() == FDE_BRUSHTYPE_Solid) {
+ argb = ((IFDE_SolidBrush*)pBrush)->GetColor();
+ }
+ CFDE_GdiFont *pGdiFont = (CFDE_GdiFont*)pFont;
+ GLYPHMETRICS gm;
+ MAT2 mat2;
+ FX_FLOAT fScale = fFontSize / 1000.0f;
+ FX_FLOAT ma, mb, mc, md;
+ FX_FLOAT fx, fy;
+ while (--iCount >= 0) {
+ mb = mc = 0;
+ ma = md = fScale;
+ if (pCharPos->m_bGlyphAdjust) {
+ FX_FLOAT aa = ma * -pCharPos->m_AdjustMatrix[0] + mb * pCharPos->m_AdjustMatrix[2];
+ FX_FLOAT bb = -ma * pCharPos->m_AdjustMatrix[1] + mb * pCharPos->m_AdjustMatrix[3];
+ FX_FLOAT cc = mc * -pCharPos->m_AdjustMatrix[0] + md * pCharPos->m_AdjustMatrix[2];
+ FX_FLOAT dd = -mc * pCharPos->m_AdjustMatrix[1] + md * pCharPos->m_AdjustMatrix[3];
+ ma = aa;
+ mb = bb;
+ mc = cc;
+ md = dd;
+ }
+ if (pMatrix) {
+ FX_FLOAT aa = ma * pMatrix->a + mb * pMatrix->c;
+ FX_FLOAT bb = ma * pMatrix->b + mb * pMatrix->d;
+ FX_FLOAT cc = mc * pMatrix->a + md * pMatrix->c;
+ FX_FLOAT dd = mc * pMatrix->b + md * pMatrix->d;
+ ma = aa;
+ mb = bb;
+ mc = cc;
+ md = dd;
+ }
+ *(long*)(&mat2.eM11) = (long)(ma * 65536);
+ *(long*)(&mat2.eM21) = (long)(mb * 65536);
+ *(long*)(&mat2.eM12) = (long)(mc * 65536);
+ *(long*)(&mat2.eM22) = (long)(md * 65536);
+ FX_DWORD dwSize = pGdiFont->GetGlyphDIBits(pCharPos->m_GlyphIndex, argb, &mat2, gm, NULL, 0);
+ if (dwSize > 0) {
+ if (m_pGlyphBuf == NULL) {
+ m_pGlyphBuf = FDE_Alloc(dwSize);
+ m_dwGlyphLen = dwSize;
+ } else if (m_dwGlyphLen < dwSize) {
+ m_pGlyphBuf = FDE_Realloc(m_pGlyphBuf, dwSize);
+ m_dwGlyphLen = dwSize;
+ }
+ pGdiFont->GetGlyphDIBits(pCharPos->m_GlyphIndex, argb, &mat2, gm, m_pGlyphBuf, m_dwGlyphLen);
+ Gdiplus::Bitmap bmp(gm.gmBlackBoxX, gm.gmBlackBoxY, gm.gmBlackBoxX * 4, PixelFormat32bppARGB, m_pGlyphBuf);
+ if (pMatrix) {
+ fx = pMatrix->a * pCharPos->m_OriginX + pMatrix->c * pCharPos->m_OriginY + pMatrix->e;
+ fy = pMatrix->b * pCharPos->m_OriginX + pMatrix->d * pCharPos->m_OriginY + pMatrix->f;
+ } else {
+ fx = pCharPos->m_OriginX;
+ fy = pCharPos->m_OriginY;
+ }
+ m_pGraphics->DrawImage(&bmp, (FXSYS_round(fx) + gm.gmptGlyphOrigin.x), (FXSYS_round(fy) - gm.gmptGlyphOrigin.y));
+ }
+ pCharPos++;
+ }
+ return TRUE;
+}
+FX_BOOL CFDE_GdiDevice::DrawArc(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ startAngle = FX_RAD2DEG(startAngle);
+ sweepAngle = FX_RAD2DEG(sweepAngle);
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawArc(pGdiPen, rect.left, rect.top, rect.width, rect.height, startAngle, sweepAngle);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawBezier(pGdiPen, pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y, pt4.x, pt4.y);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension , const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = bClosed
+ ? m_pGraphics->DrawClosedCurve(pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize(), fTension)
+ : m_pGraphics->DrawCurve(pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize(), fTension);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawEllipse(pGdiPen, rect.left, rect.top, rect.width, rect.height);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawLines(pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
+ ApplyMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawLine(pGdiPen, pt1.x, pt1.y, pt2.x, pt2.y);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix )
+{
+ CFDE_GdiPath *pGdiPath = (CFDE_GdiPath*)pPath;
+ if (pGdiPath == NULL) {
+ return FALSE;
+ }
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawPath(pGdiPen, &pGdiPath->m_Path);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawPie(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ startAngle = FX_RAD2DEG(startAngle);
+ sweepAngle = FX_RAD2DEG(sweepAngle);
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawPie(pGdiPen, rect.left, rect.top, rect.width, rect.height, startAngle, sweepAngle);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawChord(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ CFX_ArcF chord;
+ chord.Set(rect, startAngle, sweepAngle);
+ CFDE_GdiPath path;
+ path.AddChord(chord);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_GdiDevice::DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawPolygon(pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Pen *pGdiPen = CreateGdiPen(pPen, fPenWidth);
+ if (pGdiPen == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->DrawRectangle(pGdiPen, rect.left, rect.top, rect.width, rect.height);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiPen(pGdiPen);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::DrawRoundRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_SizeF &round, const CFX_Matrix *pMatrix )
+{
+ CFDE_GdiPath path;
+ path.AddRoundRectangle(rect, round);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_GdiDevice::FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension , const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillClosedCurve(pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize(), Gdiplus::FillModeAlternate, fTension);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillEllipse(pGdiBrush, rect.left, rect.top, rect.width, rect.height);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix )
+{
+ CFDE_GdiPath *pGdiPath = (CFDE_GdiPath*)pPath;
+ if (pGdiPath == NULL) {
+ return FALSE;
+ }
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillPath(pGdiBrush, &pGdiPath->m_Path);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillPie(IFDE_Brush *pBrush, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ startAngle = FX_RAD2DEG(startAngle);
+ sweepAngle = FX_RAD2DEG(sweepAngle);
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillPie(pGdiBrush, rect.left, rect.top, rect.width, rect.height, startAngle, sweepAngle);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillChord(IFDE_Brush *pBrush, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix )
+{
+ CFX_ArcF chord;
+ chord.Set(rect, startAngle, sweepAngle);
+ CFDE_GdiPath path;
+ path.AddChord(chord);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_GdiDevice::FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillPolygon(pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pBrush);
+ if (pGdiBrush == NULL) {
+ return FALSE;
+ }
+ ApplyMatrix(pMatrix);
+ Gdiplus::Status ret = m_pGraphics->FillRectangle(pGdiBrush, rect.left, rect.top, rect.width, rect.height);
+ RestoreMatrix(pMatrix);
+ ReleaseGdiBrush(pGdiBrush);
+ return ret == Gdiplus::Ok;
+}
+FX_BOOL CFDE_GdiDevice::FillRoundRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_SizeF &round, const CFX_Matrix *pMatrix )
+{
+ CFDE_GdiPath path;
+ path.AddRoundRectangle(rect, round);
+ return FillPath(pBrush, &path, pMatrix);
+}
+Gdiplus::Pen* CFDE_GdiDevice::CreateGdiPen(IFDE_Pen *pPen, FX_FLOAT fPenWidth)
+{
+ if (pPen == NULL || fPenWidth < 0.01f) {
+ return NULL;
+ }
+ Gdiplus::Pen *pGdiPen = NULL;
+ switch (pPen->GetType()) {
+ case FDE_PENTYPE_SolidColor: {
+ Gdiplus::Color gdiColor((Gdiplus::ARGB)pPen->GetColor());
+ pGdiPen = new Gdiplus::Pen(gdiColor, fPenWidth);
+ }
+ break;
+ case FDE_PENTYPE_HatchBrush:
+ case FDE_PENTYPE_TextureBrush:
+ case FDE_PENTYPE_LinearGradient: {
+ Gdiplus::Brush *pGdiBrush = CreateGdiBrush(pPen->GetBrush());
+ if (pGdiBrush) {
+ pGdiPen = new Gdiplus::Pen(pGdiBrush, fPenWidth);
+ }
+ }
+ break;
+ }
+ if (pGdiPen) {
+ CFX_FloatArray dashArray;
+ pPen->GetDashArray(dashArray);
+ pGdiPen->SetDashPattern(dashArray.GetData(), dashArray.GetSize());
+ pGdiPen->SetDashOffset(pPen->GetDashPhase());
+ pGdiPen->SetDashStyle((Gdiplus::DashStyle)pPen->GetDashStyle());
+ pGdiPen->SetStartCap((Gdiplus::LineCap)pPen->GetLineCap());
+ pGdiPen->SetEndCap((Gdiplus::LineCap)pPen->GetLineCap());
+ pGdiPen->SetLineJoin((Gdiplus::LineJoin)pPen->GetLineJoin());
+ pGdiPen->SetMiterLimit(pPen->GetMiterLimit());
+ }
+ return pGdiPen;
+}
+void CFDE_GdiDevice::ReleaseGdiPen(Gdiplus::Pen *pGdiPen)
+{
+ if (pGdiPen) {
+ ReleaseGdiBrush(pGdiPen->GetBrush());
+ delete pGdiPen;
+ }
+}
+Gdiplus::Brush* CFDE_GdiDevice::CreateGdiBrush(IFDE_Brush *pBrush)
+{
+ if (pBrush == NULL) {
+ return NULL;
+ }
+ Gdiplus::Brush *pGdiBrush = NULL;
+ switch (pBrush->GetType()) {
+ case FDE_BRUSHTYPE_Solid: {
+ IFDE_SolidBrush *pSolidBrush = (IFDE_SolidBrush*)pBrush;
+ Gdiplus::Color gdiColor((Gdiplus::ARGB)pSolidBrush->GetColor());
+ pGdiBrush = new Gdiplus::SolidBrush(gdiColor);
+ }
+ break;
+ case FDE_BRUSHTYPE_Hatch: {
+ IFDE_HatchBrush *pHatchBrush = (IFDE_HatchBrush*)pBrush;
+ Gdiplus::Color foreColor((Gdiplus::ARGB)pHatchBrush->GetColor(TRUE));
+ Gdiplus::Color backColor((Gdiplus::ARGB)pHatchBrush->GetColor(FALSE));
+ Gdiplus::HatchStyle hatchStyle = (Gdiplus::HatchStyle)pHatchBrush->GetHatchStyle();
+ pGdiBrush = new Gdiplus::HatchBrush(hatchStyle, foreColor, backColor);
+ }
+ break;
+ case FDE_BRUSHTYPE_Texture: {
+ IFDE_TextureBrush *pTextureBrush = (IFDE_TextureBrush*)pBrush;
+ CFDE_GdiImage *pImgHolder = (CFDE_GdiImage*)pTextureBrush->GetImage();
+ Gdiplus::Image *pGdiImage = pImgHolder ? pImgHolder->m_pImage : NULL;
+ Gdiplus::WrapMode wrapMode = (Gdiplus::WrapMode)pTextureBrush->GetWrapMode();
+ pGdiBrush = new Gdiplus::TextureBrush(pGdiImage, wrapMode);
+ }
+ break;
+ case FDE_BRUSHTYPE_LinearGradient: {
+ IFDE_LinearGradientBrush *pLinearBrush = (IFDE_LinearGradientBrush*)pBrush;
+ Gdiplus::WrapMode wrapMode = (Gdiplus::WrapMode)pLinearBrush->GetWrapMode();
+ CFX_PointF ptStart, ptEnd;
+ pLinearBrush->GetLinearPoints(ptStart, ptEnd);
+ FX_ARGB crStart, crEnd;
+ pLinearBrush->GetLinearColors(crStart, crEnd);
+ pGdiBrush = new Gdiplus::LinearGradientBrush((const Gdiplus::PointF&)ptStart,
+ (const Gdiplus::PointF&)ptEnd,
+ (const Gdiplus::Color&)crStart,
+ (const Gdiplus::Color&)crEnd);
+ }
+ break;
+ }
+ return pGdiBrush;
+}
+void CFDE_GdiDevice::ReleaseGdiBrush(Gdiplus::Brush *pGdiBrush)
+{
+ if (pGdiBrush) {
+ delete pGdiBrush;
+ }
+}
+void CFDE_GdiDevice::ApplyMatrix(const CFX_Matrix *pMatrix)
+{
+ if (pMatrix) {
+ m_GraphicsState = m_pGraphics->Save();
+ Gdiplus::Matrix gdiMatrix(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, pMatrix->e, pMatrix->f);
+ m_pGraphics->SetTransform(&gdiMatrix);
+ }
+}
+void CFDE_GdiDevice::RestoreMatrix(const CFX_Matrix *pMatrix)
+{
+ if (pMatrix) {
+ m_pGraphics->Restore(m_GraphicsState);
+ }
+}
+#endif
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_gdidevice.h b/xfa/src/fdp/src/fde/fde_gdidevice.h
new file mode 100644
index 0000000000..c22ed2b4ba
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_gdidevice.h
@@ -0,0 +1,76 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_GDIPLUSDEVICE_IMP
+#define _FDE_GDIPLUSDEVICE_IMP
+#ifdef _FDEPLUS
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_
+class CFDE_GdiPath;
+class CFDE_GdiDevice : public IFDE_RenderDevice, public CFX_Target
+{
+public:
+ CFDE_GdiDevice(CFX_DIBitmap *pDib);
+ ~CFDE_GdiDevice();
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_INT32 GetWidth() const;
+ virtual FX_INT32 GetHeight() const;
+ virtual FDE_HDEVICESTATE SaveState();
+ virtual void RestoreState(FDE_HDEVICESTATE hState);
+ virtual FX_BOOL SetClipPath(const IFDE_Path *pClip);
+ virtual IFDE_Path* GetClipPath() const;
+ virtual FX_BOOL SetClipRect(const CFX_RectF &rtClip);
+ virtual const CFX_RectF& GetClipRect();
+
+ virtual FX_FLOAT GetDpiX() const;
+ virtual FX_FLOAT GetDpiY() const;
+
+ virtual FX_BOOL DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix = NULL, const CFX_Matrix *pDevMatrix = NULL);
+ virtual FX_BOOL DrawImage(IFDE_Image *pImg, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix = NULL, const CFX_Matrix *pDevMatrix = NULL);
+ virtual FX_BOOL DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawArc(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPie(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawChord(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawRoundRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_SizeF &round, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPie(IFDE_Brush *pBrush, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillChord(IFDE_Brush *pBrush, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT sweepAngle, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillRoundRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_SizeF &round, const CFX_Matrix *pMatrix = NULL);
+
+protected:
+ Gdiplus::Pen* CreateGdiPen(IFDE_Pen *pPen, FX_FLOAT fPenWidth);
+ void ReleaseGdiPen(Gdiplus::Pen *pGdiPen);
+ Gdiplus::Brush* CreateGdiBrush(IFDE_Brush *pBrush);
+ void ReleaseGdiBrush(Gdiplus::Brush *pGdiBrush);
+ void ApplyMatrix(const CFX_Matrix *pMatrix);
+ void RestoreMatrix(const CFX_Matrix *pMatrix);
+ Gdiplus::GraphicsState m_GraphicsState;
+ Gdiplus::Graphics *m_pGraphics;
+ Gdiplus::Bitmap *m_pBitmap;
+ FX_LPBYTE m_pGlyphBuf;
+ FX_DWORD m_dwGlyphLen;
+ CFX_RectF m_rtClipRect;
+ CFDE_GdiPath *m_pClipPath;
+};
+#endif
+#endif
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_gedevice.cpp b/xfa/src/fdp/src/fde/fde_gedevice.cpp
new file mode 100644
index 0000000000..81d7ef5a0c
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_gedevice.cpp
@@ -0,0 +1,532 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_gedevice.h"
+#include "fde_geobject.h"
+#include "fde_devbasic.h"
+#ifndef _FDEPLUS
+#ifdef _cplusplus
+exten "C" {
+#endif
+ FX_BOOL FDE_GetStockHatchMask(FX_INT32 iHatchStyle, CFX_DIBitmap & hatchMask)
+ {
+ FDE_LPCHATCHDATA pData = FDE_DEVGetHatchData(iHatchStyle);
+ if (!pData) {
+ return FALSE;
+ }
+ hatchMask.Create(pData->iWidth, pData->iHeight, FXDIB_1bppMask);
+ FXSYS_memcpy(hatchMask.GetBuffer(), pData->MaskBits, hatchMask.GetPitch() * pData->iHeight);
+ return TRUE;
+ }
+#ifdef _cplusplus
+}
+#endif
+IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_DIBitmap *pBitmap, FX_BOOL bRgbByteOrder )
+{
+ if (pBitmap == NULL) {
+ return NULL;
+ }
+ CFX_FxgeDevice *pDevice = FX_NEW CFX_FxgeDevice;
+ if (pDevice == NULL) {
+ return NULL;
+ }
+ pDevice->Attach(pBitmap, 0, bRgbByteOrder);
+ return FDE_New CFDE_FxgeDevice(pDevice, TRUE);
+}
+IFDE_RenderDevice* IFDE_RenderDevice::Create(CFX_RenderDevice *pDevice)
+{
+ if (pDevice == NULL) {
+ return NULL;
+ }
+ return FDE_New CFDE_FxgeDevice(pDevice, FALSE);
+}
+CFDE_FxgeDevice::CFDE_FxgeDevice(CFX_RenderDevice *pDevice, FX_BOOL bOwnerDevice)
+ : m_pDevice(pDevice)
+ , m_bOwnerDevice(bOwnerDevice)
+ , m_pCharPos(NULL)
+ , m_iCharCount(0)
+{
+ FXSYS_assert(pDevice != NULL);
+ FX_RECT rt = m_pDevice->GetClipBox();
+ m_rtClip.Set((FX_FLOAT)rt.left, (FX_FLOAT)rt.top, (FX_FLOAT)rt.Width(), (FX_FLOAT)rt.Height());
+}
+CFDE_FxgeDevice::~CFDE_FxgeDevice()
+{
+ if (m_pCharPos != NULL) {
+ FDE_Free(m_pCharPos);
+ }
+ if (m_bOwnerDevice && m_pDevice) {
+ delete m_pDevice;
+ }
+}
+FX_INT32 CFDE_FxgeDevice::GetWidth() const
+{
+ return m_pDevice->GetWidth();
+}
+FX_INT32 CFDE_FxgeDevice::GetHeight() const
+{
+ return m_pDevice->GetHeight();
+}
+FDE_HDEVICESTATE CFDE_FxgeDevice::SaveState()
+{
+ m_pDevice->SaveState();
+ return NULL;
+}
+void CFDE_FxgeDevice::RestoreState(FDE_HDEVICESTATE hState)
+{
+ m_pDevice->RestoreState();
+ const FX_RECT &rt = m_pDevice->GetClipBox();
+ m_rtClip.Set((FX_FLOAT)rt.left, (FX_FLOAT)rt.top, (FX_FLOAT)rt.Width(), (FX_FLOAT)rt.Height());
+}
+FX_BOOL CFDE_FxgeDevice::SetClipRect(const CFX_RectF &rtClip)
+{
+ m_rtClip = rtClip;
+ FX_RECT rt((FX_INT32)FXSYS_floor(rtClip.left), (FX_INT32)FXSYS_floor(rtClip.top),
+ (FX_INT32)FXSYS_ceil(rtClip.right()), (FX_INT32)FXSYS_ceil(rtClip.bottom()));
+ return m_pDevice->SetClip_Rect(&rt);
+}
+const CFX_RectF& CFDE_FxgeDevice::GetClipRect()
+{
+ return m_rtClip;
+}
+FX_BOOL CFDE_FxgeDevice::SetClipPath(const IFDE_Path *pClip)
+{
+ return FALSE;
+}
+IFDE_Path* CFDE_FxgeDevice::GetClipPath() const
+{
+ return NULL;
+}
+FX_FLOAT CFDE_FxgeDevice::GetDpiX() const
+{
+ return 96;
+}
+FX_FLOAT CFDE_FxgeDevice::GetDpiY() const
+{
+ return 96;
+}
+FX_BOOL CFDE_FxgeDevice::DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix, const CFX_Matrix *pDevMatrix)
+{
+ FXSYS_assert(pDib != NULL);
+ CFX_RectF srcRect;
+ if (pSrcRect) {
+ srcRect = *pSrcRect;
+ } else {
+ srcRect.Set(0, 0, (FX_FLOAT)pDib->GetWidth(), (FX_FLOAT)pDib->GetHeight());
+ }
+ if (srcRect.IsEmpty()) {
+ return FALSE;
+ }
+ CFX_Matrix dib2fxdev;
+ if (pImgMatrix) {
+ dib2fxdev = *pImgMatrix;
+ } else {
+ dib2fxdev.Reset();
+ }
+ dib2fxdev.a = dstRect.width;
+ dib2fxdev.d = -dstRect.height;
+ dib2fxdev.e = dstRect.left;
+ dib2fxdev.f = dstRect.bottom();
+ if (pDevMatrix) {
+ dib2fxdev.Concat(*pDevMatrix);
+ }
+ FX_LPVOID handle = NULL;
+ m_pDevice->StartDIBits(pDib, 255, 0, (const CFX_AffineMatrix*)&dib2fxdev, 0, handle);
+ while (m_pDevice->ContinueDIBits(handle, NULL)) { }
+ m_pDevice->CancelDIBits(handle);
+ return handle != NULL;
+}
+FX_BOOL CFDE_FxgeDevice::DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pBrush != NULL && pFont != NULL && pCharPos != NULL && iCount > 0);
+ CFX_FontCache *pCache = CFX_GEModule::Get()->GetFontCache();
+ CFX_Font *pFxFont = (CFX_Font*)pFont->GetDevFont();
+ switch (pBrush->GetType()) {
+ case FDE_BRUSHTYPE_Solid: {
+ FX_ARGB argb = ((IFDE_SolidBrush*)pBrush)->GetColor();
+ if ((pFont->GetFontStyles() & FX_FONTSTYLE_Italic) != 0 && !pFxFont->IsItalic()) {
+ FXTEXT_CHARPOS *pCP = (FXTEXT_CHARPOS*)pCharPos;
+ FX_FLOAT *pAM;
+ for (FX_INT32 i = 0; i < iCount; ++i) {
+ static const FX_FLOAT mc = 0.267949f;
+ pAM = pCP->m_AdjustMatrix;
+ pAM[2] = mc * pAM[0] + pAM[2];
+ pAM[3] = mc * pAM[1] + pAM[3];
+ pCP ++;
+ }
+ }
+ FXTEXT_CHARPOS *pCP = (FXTEXT_CHARPOS*)pCharPos;
+ IFX_Font *pCurFont = NULL;
+ IFX_Font *pSTFont = NULL;
+ FXTEXT_CHARPOS *pCurCP = NULL;
+ FX_INT32 iCurCount = 0;
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FX_DWORD dwFontStyle = pFont->GetFontStyles();
+ CFX_Font FxFont;
+ CFX_SubstFont SubstFxFont;
+ FxFont.m_pSubstFont = &SubstFxFont;
+ SubstFxFont.m_Weight = dwFontStyle & FX_FONTSTYLE_Bold ? 700 : 400;
+ SubstFxFont.m_WeightCJK = SubstFxFont.m_Weight;
+ SubstFxFont.m_ItalicAngle = dwFontStyle & FX_FONTSTYLE_Italic ? -12 : 0;
+ SubstFxFont.m_bItlicCJK = dwFontStyle & FX_FONTSTYLE_Italic ? TRUE : FALSE;
+#endif
+ for (FX_INT32 i = 0; i < iCount; ++i) {
+ pSTFont = pFont->GetSubstFont((FX_INT32)pCP->m_GlyphIndex);
+ pCP->m_GlyphIndex &= 0x00FFFFFF;
+ pCP->m_bFontStyle = FALSE;
+ if (pCurFont != pSTFont) {
+ if (pCurFont != NULL) {
+ pFxFont = (CFX_Font*)pCurFont->GetDevFont();
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FxFont.m_Face = pFxFont->m_Face;
+ m_pDevice->DrawNormalText(iCurCount, pCurCP, &FxFont, pCache, -fFontSize, (const CFX_AffineMatrix*)pMatrix, argb, FXTEXT_CLEARTYPE);
+#else
+ m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, pCache, -fFontSize, (const CFX_AffineMatrix*)pMatrix, argb, FXTEXT_CLEARTYPE);
+#endif
+ }
+ pCurFont = pSTFont;
+ pCurCP = pCP;
+ iCurCount = 1;
+ } else {
+ iCurCount ++;
+ }
+ pCP ++;
+ }
+ if (pCurFont != NULL && iCurCount) {
+ pFxFont = (CFX_Font*)pCurFont->GetDevFont();
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FxFont.m_Face = pFxFont->m_Face;
+ FX_BOOL bRet = m_pDevice->DrawNormalText(iCurCount, pCurCP, &FxFont, pCache, -fFontSize, (const CFX_AffineMatrix*)pMatrix, argb, FXTEXT_CLEARTYPE);
+ FxFont.m_pSubstFont = NULL;
+ FxFont.m_Face = NULL;
+ return bRet;
+#else
+ return m_pDevice->DrawNormalText(iCurCount, pCurCP, pFxFont, pCache, -fFontSize, (const CFX_AffineMatrix*)pMatrix, argb, FXTEXT_CLEARTYPE);
+#endif
+ }
+#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
+ FxFont.m_pSubstFont = NULL;
+ FxFont.m_Face = NULL;
+#endif
+ return TRUE;
+ }
+ break;
+ default:
+ return FALSE;
+ }
+}
+FX_BOOL CFDE_FxgeDevice::DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix )
+{
+ CFX_PointsF points;
+ points.Add(pt1);
+ points.Add(pt2);
+ points.Add(pt3);
+ points.Add(pt4);
+ CFDE_Path path;
+ path.AddBezier(points);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension , const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddCurve(points, bClosed, fTension);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddEllipse(rect);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddLines(points);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddLine(pt1, pt2);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path *pGePath = (CFDE_Path*)pPath;
+ if (pGePath == NULL) {
+ return FALSE;
+ }
+ CFX_GraphStateData graphState;
+ if (!CreatePen(pPen, fPenWidth, graphState)) {
+ return FALSE;
+ }
+ return m_pDevice->DrawPath(&pGePath->m_Path, (const CFX_AffineMatrix*)pMatrix, &graphState, 0, pPen->GetColor(), 0);
+}
+FX_BOOL CFDE_FxgeDevice::DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddPolygon(points);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddRectangle(rect);
+ return DrawPath(pPen, fPenWidth, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension , const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddCurve(points, TRUE, fTension);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddEllipse(rect);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddPolygon(points);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix )
+{
+ CFDE_Path path;
+ path.AddRectangle(rect);
+ return FillPath(pBrush, &path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::CreatePen(IFDE_Pen *pPen, FX_FLOAT fPenWidth, CFX_GraphStateData &graphState)
+{
+ if (pPen == NULL) {
+ return FALSE;
+ }
+ graphState.m_LineCap = (CFX_GraphStateData::LineCap)pPen->GetLineCap();
+ graphState.m_LineJoin = (CFX_GraphStateData::LineJoin)pPen->GetLineJoin();
+ graphState.m_LineWidth = fPenWidth;
+ graphState.m_MiterLimit = pPen->GetMiterLimit();
+ graphState.m_DashPhase = pPen->GetDashPhase();
+ CFX_FloatArray dashArray;
+ switch (pPen->GetDashStyle()) {
+ case FDE_DASHSTYLE_Dash:
+ dashArray.Add(3);
+ dashArray.Add(1);
+ break;
+ case FDE_DASHSTYLE_Dot:
+ dashArray.Add(1);
+ dashArray.Add(1);
+ break;
+ case FDE_DASHSTYLE_DashDot:
+ dashArray.Add(3);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ break;
+ case FDE_DASHSTYLE_DashDotDot:
+ dashArray.Add(3);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ dashArray.Add(1);
+ break;
+ case FDE_DASHSTYLE_Customized:
+ pPen->GetDashArray(dashArray);
+ break;
+ }
+ FX_INT32 iDashCount = dashArray.GetSize();
+ if (iDashCount > 0) {
+ graphState.SetDashCount(iDashCount);
+ for (FX_INT32 i = 0; i < iDashCount; ++i) {
+ graphState.m_DashArray[i] = dashArray[i] * fPenWidth;
+ }
+ }
+ return TRUE;
+}
+typedef FX_BOOL (CFDE_FxgeDevice::*pfFillPath)(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+static const pfFillPath gs_FillPath[] = {
+ &CFDE_FxgeDevice::FillSolidPath,
+ &CFDE_FxgeDevice::FillHatchPath,
+ &CFDE_FxgeDevice::FillTexturePath,
+ &CFDE_FxgeDevice::FillLinearGradientPath,
+};
+FX_BOOL CFDE_FxgeDevice::FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix)
+{
+ CFDE_Path *pGePath = (CFDE_Path*)pPath;
+ if (pGePath == NULL) {
+ return FALSE;
+ }
+ if (pBrush == NULL) {
+ return FALSE;
+ }
+ FX_INT32 iType = pBrush->GetType();
+ if (iType < 0 || iType > FDE_BRUSHTYPE_MAX) {
+ return FALSE;
+ }
+ return (this->*gs_FillPath[iType])(pBrush, &pGePath->m_Path, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::FillSolidPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_Solid);
+ IFDE_SolidBrush *pSolidBrush = (IFDE_SolidBrush*)pBrush;
+ return m_pDevice->DrawPath(pPath, (const CFX_AffineMatrix*)pMatrix, NULL, pSolidBrush->GetColor(), 0, FXFILL_WINDING);
+}
+FX_BOOL CFDE_FxgeDevice::FillHatchPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_Hatch);
+ IFDE_HatchBrush *pHatchBrush = (IFDE_HatchBrush*)pBrush;
+ FX_INT32 iStyle = pHatchBrush->GetHatchStyle();
+ if (iStyle < FDE_HATCHSTYLE_Min || iStyle > FDE_HATCHSTYLE_Max) {
+ return FALSE;
+ }
+ CFX_DIBitmap mask;
+ if (!FDE_GetStockHatchMask(iStyle, mask)) {
+ return FALSE;
+ }
+ FX_ARGB dwForeColor = pHatchBrush->GetColor(TRUE);
+ FX_ARGB dwBackColor = pHatchBrush->GetColor(FALSE);
+ CFX_FloatRect rectf = pPath->GetBoundingBox();
+ if (pMatrix) {
+ rectf.Transform((const CFX_AffineMatrix*)pMatrix);
+ }
+ FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
+ FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
+ m_pDevice->SaveState();
+ m_pDevice->StartRendering();
+ m_pDevice->SetClip_PathFill(pPath, (const CFX_AffineMatrix*)pMatrix, FXFILL_WINDING);
+ m_pDevice->FillRect(&rect, dwBackColor);
+ for (FX_INT32 j = rect.bottom; j < rect.top; j += mask.GetHeight())
+ for (FX_INT32 i = rect.left; i < rect.right; i += mask.GetWidth()) {
+ m_pDevice->SetBitMask(&mask, i, j, dwForeColor);
+ }
+ m_pDevice->EndRendering();
+ m_pDevice->RestoreState();
+ return TRUE;
+}
+FX_BOOL CFDE_FxgeDevice::FillTexturePath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_Texture);
+ IFDE_TextureBrush *pTextureBrush = (IFDE_TextureBrush*)pBrush;
+ IFDE_Image *pImage = (IFDE_Image*)pTextureBrush->GetImage();
+ if (pImage == NULL) {
+ return FALSE;
+ }
+ CFX_Size size;
+ size.Set(pImage->GetImageWidth(), pImage->GetImageHeight());
+ CFX_DIBitmap bmp;
+ bmp.Create(size.x, size.y, FXDIB_Argb);
+ if (!pImage->StartLoadImage(&bmp, 0, 0, size.x, size.y, 0, 0, size.x, size.y)) {
+ return FALSE;
+ }
+ if (pImage->DoLoadImage() < 100) {
+ return FALSE;
+ }
+ pImage->StopLoadImage();
+ return WrapTexture(pTextureBrush->GetWrapMode(), &bmp, pPath, pMatrix);
+}
+FX_BOOL CFDE_FxgeDevice::WrapTexture(FX_INT32 iWrapMode, const CFX_DIBitmap *pBitmap, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ CFX_FloatRect rectf = pPath->GetBoundingBox();
+ if (pMatrix) {
+ rectf.Transform((const CFX_AffineMatrix*)pMatrix);
+ }
+ FX_RECT rect(FXSYS_round(rectf.left), FXSYS_round(rectf.top),
+ FXSYS_round(rectf.right), FXSYS_round(rectf.bottom));
+ rect.Normalize();
+ if (rect.IsEmpty()) {
+ return FALSE;
+ }
+ m_pDevice->SaveState();
+ m_pDevice->StartRendering();
+ m_pDevice->SetClip_PathFill(pPath, (const CFX_AffineMatrix*)pMatrix, FXFILL_WINDING);
+ switch (iWrapMode) {
+ case FDE_WRAPMODE_Tile:
+ case FDE_WRAPMODE_TileFlipX:
+ case FDE_WRAPMODE_TileFlipY:
+ case FDE_WRAPMODE_TileFlipXY: {
+ FX_BOOL bFlipX = iWrapMode == FDE_WRAPMODE_TileFlipXY || iWrapMode == FDE_WRAPMODE_TileFlipX;
+ FX_BOOL bFlipY = iWrapMode == FDE_WRAPMODE_TileFlipXY || iWrapMode == FDE_WRAPMODE_TileFlipY;
+ const CFX_DIBitmap *pFlip[2][2];
+ pFlip[0][0] = pBitmap;
+ pFlip[0][1] = bFlipX ? pBitmap->FlipImage(TRUE, FALSE) : pBitmap;
+ pFlip[1][0] = bFlipY ? pBitmap->FlipImage(FALSE, TRUE) : pBitmap;
+ pFlip[1][1] = (bFlipX || bFlipY) ? pBitmap->FlipImage(bFlipX, bFlipY) : pBitmap;
+ FX_INT32 iCounterY = 0;
+ for (FX_INT32 j = rect.top; j < rect.bottom; j += pBitmap->GetHeight()) {
+ FX_INT32 indexY = iCounterY++ % 2;
+ FX_INT32 iCounterX = 0;
+ for (FX_INT32 i = rect.left; i < rect.right; i += pBitmap->GetWidth()) {
+ FX_INT32 indexX = iCounterX++ % 2;
+ m_pDevice->SetDIBits(pFlip[indexY][indexX], i, j);
+ }
+ }
+ if (pFlip[0][1] != pFlip[0][0]) {
+ delete pFlip[0][1];
+ }
+ if (pFlip[1][0] != pFlip[0][0]) {
+ delete pFlip[1][0];
+ }
+ if (pFlip[1][1] != pFlip[0][0]) {
+ delete pFlip[1][1];
+ }
+ }
+ break;
+ case FDE_WRAPMODE_Clamp: {
+ m_pDevice->SetDIBits(pBitmap, rect.left, rect.bottom);
+ }
+ break;
+ }
+ m_pDevice->EndRendering();
+ m_pDevice->RestoreState();
+ return TRUE;
+}
+FX_BOOL CFDE_FxgeDevice::FillLinearGradientPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix)
+{
+ FXSYS_assert(pPath && pBrush && pBrush->GetType() == FDE_BRUSHTYPE_LinearGradient);
+ IFDE_LinearGradientBrush *pLinearBrush = (IFDE_LinearGradientBrush*)pBrush;
+ CFX_PointF pt0, pt1;
+ pLinearBrush->GetLinearPoints(pt0, pt1);
+ CFX_VectorF fDiagonal;
+ fDiagonal.Set(pt0, pt1);
+ FX_FLOAT fTheta = FXSYS_atan2(fDiagonal.y, fDiagonal.x);
+ FX_FLOAT fLength = fDiagonal.Length();
+ FX_FLOAT fTotalX = fLength / FXSYS_cos(fTheta);
+ FX_FLOAT fTotalY = fLength / FXSYS_cos(FX_PI / 2 - fTheta);
+ FX_FLOAT fSteps = FX_MAX(fTotalX, fTotalY);
+ FX_FLOAT dx = fTotalX / fSteps;
+ FX_FLOAT dy = fTotalY / fSteps;
+ FX_ARGB cr0, cr1;
+ pLinearBrush->GetLinearColors(cr0, cr1);
+ FX_FLOAT a0 = FXARGB_A(cr0);
+ FX_FLOAT r0 = FXARGB_R(cr0);
+ FX_FLOAT g0 = FXARGB_G(cr0);
+ FX_FLOAT b0 = FXARGB_B(cr0);
+ FX_FLOAT da = (FXARGB_A(cr1) - a0) / fSteps;
+ FX_FLOAT dr = (FXARGB_R(cr1) - r0) / fSteps;
+ FX_FLOAT dg = (FXARGB_G(cr1) - g0) / fSteps;
+ FX_FLOAT db = (FXARGB_B(cr1) - b0) / fSteps;
+ CFX_DIBitmap bmp;
+ bmp.Create(FXSYS_round(FXSYS_fabs(fDiagonal.x)), FXSYS_round(FXSYS_fabs(fDiagonal.y)), FXDIB_Argb);
+ CFX_FxgeDevice dev;
+ dev.Attach(&bmp);
+ pt1 = pt0;
+ FX_INT32 iSteps = FXSYS_round(FXSYS_ceil(fSteps));
+ while (--iSteps >= 0) {
+ cr0 = ArgbEncode(FXSYS_round(a0), FXSYS_round(r0), FXSYS_round(g0), FXSYS_round(b0));
+ dev.DrawCosmeticLine(pt0.x, pt0.y, pt1.x, pt1.y, cr0);
+ pt1.x += dx;
+ pt0.y += dy;
+ a0 += da;
+ r0 += dr;
+ g0 += dg;
+ b0 += db;
+ }
+ return WrapTexture(pLinearBrush->GetWrapMode(), &bmp, pPath, pMatrix);
+}
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_gedevice.h b/xfa/src/fdp/src/fde/fde_gedevice.h
new file mode 100644
index 0000000000..6290e53390
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_gedevice.h
@@ -0,0 +1,63 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_FXGEDEVICE_IMP
+#define _FDE_FXGEDEVICE_IMP
+#ifndef _FDEPLUS
+class CFDE_FxgeDevice : public IFDE_RenderDevice, public CFX_Target
+{
+public:
+ CFDE_FxgeDevice(CFX_RenderDevice *pDevice, FX_BOOL bOwnerDevice);
+ ~CFDE_FxgeDevice();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_INT32 GetWidth() const;
+ virtual FX_INT32 GetHeight() const;
+ virtual FDE_HDEVICESTATE SaveState();
+ virtual void RestoreState(FDE_HDEVICESTATE hState);
+ virtual FX_BOOL SetClipPath(const IFDE_Path *pClip);
+ virtual IFDE_Path* GetClipPath() const;
+ virtual FX_BOOL SetClipRect(const CFX_RectF &rtClip);
+ virtual const CFX_RectF& GetClipRect();
+
+ virtual FX_FLOAT GetDpiX() const;
+ virtual FX_FLOAT GetDpiY() const;
+
+ virtual FX_BOOL DrawImage(CFX_DIBSource *pDib, const CFX_RectF *pSrcRect, const CFX_RectF &dstRect, const CFX_Matrix *pImgMatrix = NULL, const CFX_Matrix *pDevMatrix = NULL);
+ virtual FX_BOOL DrawString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawBezier(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_PointF &pt3, const CFX_PointF &pt4, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawCurve(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawEllipse(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawLines(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawLine(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointF &pt1, const CFX_PointF &pt2, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPath(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawPolygon(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL DrawRectangle(IFDE_Pen *pPen, FX_FLOAT fPenWidth, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillClosedCurve(IFDE_Brush *pBrush, const CFX_PointsF &points, FX_FLOAT fTension = 0.5f, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillEllipse(IFDE_Brush* pBrush, const CFX_RectF& rect, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPath(IFDE_Brush *pBrush, const IFDE_Path *pPath, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillPolygon(IFDE_Brush *pBrush, const CFX_PointsF &points, const CFX_Matrix *pMatrix = NULL);
+ virtual FX_BOOL FillRectangle(IFDE_Brush *pBrush, const CFX_RectF &rect, const CFX_Matrix *pMatrix = NULL);
+ FX_BOOL FillSolidPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ FX_BOOL FillHatchPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ FX_BOOL FillTexturePath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ FX_BOOL FillLinearGradientPath(IFDE_Brush *pBrush, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ FX_BOOL DrawSolidString(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix);
+ FX_BOOL DrawStringPath(IFDE_Brush *pBrush, IFX_Font *pFont, const FXTEXT_CHARPOS *pCharPos, FX_INT32 iCount, FX_FLOAT fFontSize, const CFX_Matrix *pMatrix);
+protected:
+ FX_BOOL CreatePen(IFDE_Pen *pPen, FX_FLOAT fPenWidth, CFX_GraphStateData &graphState);
+ FX_BOOL WrapTexture(FX_INT32 iWrapMode, const CFX_DIBitmap *pBitmap, const CFX_PathData *pPath, const CFX_Matrix *pMatrix);
+ CFX_RenderDevice *m_pDevice;
+ CFX_RectF m_rtClip;
+ FX_BOOL m_bOwnerDevice;
+ FXTEXT_CHARPOS *m_pCharPos;
+ FX_INT32 m_iCharCount;
+};
+#endif
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_geobject.cpp b/xfa/src/fdp/src/fde/fde_geobject.cpp
new file mode 100644
index 0000000000..9f34cf3051
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_geobject.cpp
@@ -0,0 +1,270 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_object.h"
+#include "fde_geobject.h"
+#ifndef _FDEPLUS
+IFDE_Path* IFDE_Path::Create()
+{
+ return FDE_New CFDE_Path;
+}
+FX_BOOL CFDE_Path::StartFigure()
+{
+ return CloseFigure();
+}
+FX_BOOL CFDE_Path::CloseFigure()
+{
+ FX_PATHPOINT *pPoint = GetLastPoint();
+ if (pPoint) {
+ pPoint->m_Flag |= FXPT_CLOSEFIGURE;
+ }
+ return TRUE;
+}
+FX_PATHPOINT* CFDE_Path::GetLastPoint(FX_INT32 iCount ) const
+{
+ if (iCount < 1) {
+ return NULL;
+ }
+ FX_INT32 iPoints = m_Path.GetPointCount();
+ if (iCount > iPoints) {
+ return NULL;
+ }
+ return m_Path.GetPoints() + iPoints - iCount;
+}
+FX_BOOL CFDE_Path::FigureClosed() const
+{
+ FX_PATHPOINT *pPoint = GetLastPoint();
+ return pPoint ? (pPoint->m_Flag & FXPT_CLOSEFIGURE) : TRUE;
+}
+FX_PATHPOINT* CFDE_Path::AddPoints(FX_INT32 iCount)
+{
+ if (iCount < 1) {
+ return NULL;
+ }
+ FX_INT32 iPoints = m_Path.GetPointCount();
+ m_Path.AddPointCount(iCount);
+ return m_Path.GetPoints() + iPoints;
+}
+void CFDE_Path::MoveTo(FX_FLOAT fx, FX_FLOAT fy)
+{
+ FX_PATHPOINT *pPoint = AddPoints(1);
+ pPoint->m_PointX = fx;
+ pPoint->m_PointY = fy;
+ pPoint->m_Flag = FXPT_MOVETO;
+}
+void CFDE_Path::LineTo(FX_FLOAT fx, FX_FLOAT fy)
+{
+ FX_PATHPOINT *pPoint = AddPoints(1);
+ pPoint->m_PointX = fx;
+ pPoint->m_PointY = fy;
+ pPoint->m_Flag = FXPT_LINETO;
+}
+void CFDE_Path::BezierTo(const CFX_PointF &p1, const CFX_PointF &p2, const CFX_PointF &p3)
+{
+ FX_PATHPOINT *p = AddPoints(3);
+ p[0].m_PointX = p1.x;
+ p[0].m_PointY = p1.y;
+ p[0].m_Flag = FXPT_BEZIERTO;
+ p[1].m_PointX = p2.x;
+ p[1].m_PointY = p2.y;
+ p[1].m_Flag = FXPT_BEZIERTO;
+ p[2].m_PointX = p3.x;
+ p[2].m_PointY = p3.y;
+ p[2].m_Flag = FXPT_BEZIERTO;
+}
+void CFDE_Path::ArcTo(FX_BOOL bStart, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT endAngle)
+{
+ FX_FLOAT rx = rect.width / 2;
+ FX_FLOAT ry = rect.height / 2;
+ FX_FLOAT cx = rect.left + rx;
+ FX_FLOAT cy = rect.top + ry;
+ FX_FLOAT alpha = FXSYS_atan2(rx * FXSYS_sin(startAngle), ry * FXSYS_cos(startAngle));
+ FX_FLOAT beta = FXSYS_atan2(rx * FXSYS_sin(endAngle), ry * FXSYS_cos(endAngle));
+ if (FXSYS_fabs(beta - alpha) > FX_PI) {
+ if (beta > alpha) {
+ beta -= 2 * FX_PI;
+ } else {
+ alpha -= 2 * FX_PI;
+ }
+ }
+ FX_FLOAT half_delta = (beta - alpha) / 2;
+ FX_FLOAT bcp = 4.0f / 3 * (1 - FXSYS_cos(half_delta)) / FXSYS_sin(half_delta);
+ FX_FLOAT sin_alpha = FXSYS_sin(alpha);
+ FX_FLOAT sin_beta = FXSYS_sin(beta);
+ FX_FLOAT cos_alpha = FXSYS_cos(alpha);
+ FX_FLOAT cos_beta = FXSYS_cos(beta);
+ if (bStart) {
+ CFX_PointF p0;
+ p0.Set(cx + rx * cos_alpha, cy + ry * sin_alpha);
+ MoveTo(p0);
+ }
+ CFX_PointF p1;
+ p1.Set(cx + rx * (cos_alpha - bcp * sin_alpha), cy + ry * (sin_alpha + bcp * cos_alpha));
+ CFX_PointF p2;
+ p2.Set(cx + rx * (cos_beta + bcp * sin_beta), cy + ry * (sin_beta - bcp * cos_beta));
+ CFX_PointF p3;
+ p3.Set(cx + rx * cos_beta, cy + ry * sin_beta);
+ BezierTo(p1, p2, p3);
+}
+void CFDE_Path::AddBezier(const CFX_PointsF &points)
+{
+ if (points.GetSize() != 4) {
+ return;
+ }
+ FX_LPCPOINTF p = points.GetData();
+ MoveTo(p[0]);
+ BezierTo(p[1], p[2], p[3]);
+}
+void CFDE_Path::AddBeziers(const CFX_PointsF &points)
+{
+ FX_INT32 iCount = points.GetSize();
+ if (iCount < 4) {
+ return;
+ }
+ FX_LPCPOINTF p = points.GetData();
+ FX_LPCPOINTF pEnd = p + iCount;
+ MoveTo(p[0]);
+ for (++p; p <= pEnd - 3; p += 3) {
+ BezierTo(p[0], p[1], p[2]);
+ }
+}
+void CFDE_Path::GetCurveTangents(const CFX_PointsF &points, CFX_PointsF &tangents, FX_BOOL bClosed, FX_FLOAT fTension) const
+{
+ FX_INT32 iCount = points.GetSize();
+ tangents.SetSize(iCount);
+ if (iCount < 3) {
+ return;
+ }
+ FX_FLOAT fCoefficient = fTension / 3.0f;
+ FX_LPCPOINTF pPoints = points.GetData();
+ FX_LPPOINTF pTangents = tangents.GetData();
+ for (FX_INT32 i = 0; i < iCount; ++i) {
+ FX_INT32 r = i + 1;
+ FX_INT32 s = i - 1;
+ if (r >= iCount) {
+ r = bClosed ? (r - iCount) : (iCount - 1);
+ }
+ if (s < 0) {
+ s = bClosed ? (s + iCount) : 0;
+ }
+ pTangents[i].x += (fCoefficient * (pPoints[r].x - pPoints[s].x));
+ pTangents[i].y += (fCoefficient * (pPoints[r].y - pPoints[s].y));
+ }
+}
+void CFDE_Path::AddCurve(const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension)
+{
+ FX_INT32 iLast = points.GetUpperBound();
+ if (iLast < 1) {
+ return;
+ }
+ CFX_PointsF tangents;
+ GetCurveTangents(points, tangents, bClosed, fTension);
+ FX_LPCPOINTF pPoints = points.GetData();
+ FX_LPPOINTF pTangents = tangents.GetData();
+ MoveTo(pPoints[0]);
+ for (FX_INT32 i = 0; i < iLast; ++i) {
+ FX_INT32 j = i + 1;
+ CFX_PointF p1;
+ p1.Set(pPoints[i].x + pTangents[i].x, pPoints[i].y + pTangents[i].y);
+ CFX_PointF p2;
+ p2.Set(pPoints[j].x - pTangents[j].x, pPoints[j].y - pTangents[j].y);
+ CFX_PointF p3;
+ p3.Set(pPoints[j].x, pPoints[j].y);
+ BezierTo(p1, p2, p3);
+ }
+ if (bClosed) {
+ CFX_PointF p1;
+ p1.Set(pPoints[iLast].x + pTangents[iLast].x, pPoints[iLast].y + pTangents[iLast].y);
+ CFX_PointF p2;
+ p2.Set(pPoints[0].x - pTangents[0].x, pPoints[0].y - pTangents[0].y);
+ CFX_PointF p3;
+ p3.Set(pPoints[0].x, pPoints[0].y);
+ BezierTo(p1, p2, p3);
+ CloseFigure();
+ }
+}
+void CFDE_Path::AddEllipse(const CFX_RectF &rect)
+{
+ FX_FLOAT fStartAngle = 0;
+ FX_FLOAT fEndAngle = FX_PI / 2;
+ for (FX_INT32 i = 0; i < 4; ++i) {
+ ArcTo(i == 0, rect, fStartAngle, fEndAngle);
+ fStartAngle += FX_PI / 2;
+ fEndAngle += FX_PI / 2;
+ }
+ CloseFigure();
+}
+void CFDE_Path::AddLine(const CFX_PointF &pt1, const CFX_PointF &pt2)
+{
+ FX_PATHPOINT *pLast = GetLastPoint();
+ if (pLast == NULL || FXSYS_fabs(pLast->m_PointX - pt1.x) > 0.001 || FXSYS_fabs(pLast->m_PointY - pt1.y) > 0.001) {
+ MoveTo(pt1);
+ }
+ LineTo(pt2);
+}
+void CFDE_Path::AddPath(const IFDE_Path *pSrc, FX_BOOL bConnect)
+{
+ CFDE_Path *pPath = (CFDE_Path*)pSrc;
+ if (pPath == NULL) {
+ return;
+ }
+ FX_INT32 iCount = pPath->m_Path.GetPointCount();
+ if (iCount < 1) {
+ return;
+ }
+ if (bConnect) {
+ LineTo(pPath->m_Path.GetPointX(0), pPath->m_Path.GetPointY(0));
+ }
+ m_Path.Append(&pPath->m_Path, NULL);
+}
+void CFDE_Path::AddPolygon(const CFX_PointsF &points)
+{
+ FX_INT32 iCount = points.GetSize();
+ if (iCount < 2) {
+ return;
+ }
+ AddLines(points);
+ FX_LPCPOINTF p = points.GetData();
+ if (FXSYS_fabs(p[0].x - p[iCount - 1].x) < 0.01f || FXSYS_fabs(p[0].y - p[iCount - 1].y) < 0.01f) {
+ LineTo(p[0]);
+ }
+ CloseFigure();
+}
+void CFDE_Path::AddLines(const CFX_PointsF &points)
+{
+ FX_INT32 iCount = points.GetSize();
+ if (iCount < 2) {
+ return;
+ }
+ FX_LPCPOINTF p = points.GetData();
+ FX_LPCPOINTF pEnd = p + iCount;
+ MoveTo(p[0]);
+ for (++p; p < pEnd; ++p) {
+ LineTo(*p);
+ }
+}
+void CFDE_Path::AddRectangle(const CFX_RectF &rect)
+{
+ MoveTo(rect.TopLeft());
+ LineTo(rect.TopRight());
+ LineTo(rect.BottomRight());
+ LineTo(rect.BottomLeft());
+ CloseFigure();
+}
+void CFDE_Path::GetBBox(CFX_RectF &bbox) const
+{
+ CFX_FloatRect rect = m_Path.GetBoundingBox();
+ bbox.Set(rect.left, rect.top, rect.Width(), rect.Height());
+ bbox.Normalize();
+}
+void CFDE_Path::GetBBox(CFX_RectF &bbox, FX_FLOAT fLineWidth, FX_FLOAT fMiterLimit) const
+{
+ CFX_FloatRect rect = m_Path.GetBoundingBox(fLineWidth, fMiterLimit);
+ bbox.Set(rect.left, rect.top, rect.Width(), rect.Height());
+ bbox.Normalize();
+}
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_geobject.h b/xfa/src/fdp/src/fde/fde_geobject.h
new file mode 100644
index 0000000000..8552b6f7b8
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_geobject.h
@@ -0,0 +1,53 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_GRAPHOBJS_IMP
+#define _FDE_GRAPHOBJS_IMP
+#ifndef _FDEPLUS
+#include "../../../foxitlib.h"
+class CFDE_GEFontMgr;
+class CFDE_Path : public IFDE_Path, public CFX_Target
+{
+public:
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_BOOL StartFigure();
+ virtual FX_BOOL CloseFigure();
+
+ virtual void AddBezier(const CFX_PointsF &points);
+ virtual void AddBeziers(const CFX_PointsF &points);
+ virtual void AddCurve(const CFX_PointsF &points, FX_BOOL bClosed, FX_FLOAT fTension = 0.5f);
+ virtual void AddEllipse(const CFX_RectF &rect);
+ virtual void AddLines(const CFX_PointsF &points);
+ virtual void AddLine(const CFX_PointF &pt1, const CFX_PointF &pt2);
+ virtual void AddPath(const IFDE_Path *pSrc, FX_BOOL bConnect);
+ virtual void AddPolygon(const CFX_PointsF &points);
+ virtual void AddRectangle(const CFX_RectF &rect);
+ virtual void GetBBox(CFX_RectF &bbox) const;
+ virtual void GetBBox(CFX_RectF &bbox, FX_FLOAT fLineWidth, FX_FLOAT fMiterLimit) const;
+ FX_PATHPOINT* AddPoints(FX_INT32 iCount);
+ FX_PATHPOINT* GetLastPoint(FX_INT32 iCount = 1) const;
+ FX_BOOL FigureClosed() const;
+ void MoveTo(FX_FLOAT fx, FX_FLOAT fy);
+ void LineTo(FX_FLOAT fx, FX_FLOAT fy);
+ void BezierTo(const CFX_PointF &p1, const CFX_PointF &p2, const CFX_PointF &p3);
+ void ArcTo(FX_BOOL bStart, const CFX_RectF &rect, FX_FLOAT startAngle, FX_FLOAT endAngle);
+ void MoveTo(const CFX_PointF &p0)
+ {
+ MoveTo(p0.x, p0.y);
+ }
+ void LineTo(const CFX_PointF &p1)
+ {
+ LineTo(p1.x, p1.y);
+ }
+ void GetCurveTangents(const CFX_PointsF &points, CFX_PointsF &tangents, FX_BOOL bClosed, FX_FLOAT fTension) const;
+ CFX_PathData m_Path;
+};
+#endif
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_iterator.cpp b/xfa/src/fdp/src/fde/fde_iterator.cpp
new file mode 100644
index 0000000000..5f6e0aa7e8
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_iterator.cpp
@@ -0,0 +1,101 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_iterator.h"
+IFDE_VisualSetIterator* IFDE_VisualSetIterator::Create()
+{
+ return FDE_New CFDE_VisualSetIterator;
+}
+CFDE_VisualSetIterator::CFDE_VisualSetIterator()
+ : m_dwFilter(0)
+{
+}
+CFDE_VisualSetIterator::~CFDE_VisualSetIterator()
+{
+ m_CanvasStack.RemoveAll();
+}
+FX_BOOL CFDE_VisualSetIterator::AttachCanvas(IFDE_CanvasSet *pCanvas)
+{
+ FXSYS_assert(pCanvas != NULL);
+ m_CanvasStack.RemoveAll();
+ FDE_CANVASITEM canvas;
+ canvas.hCanvas = NULL;
+ canvas.pCanvas = pCanvas;
+ canvas.hPos = pCanvas->GetFirstPosition(NULL);
+ if (canvas.hPos == NULL) {
+ return FALSE;
+ }
+ return m_CanvasStack.Push(canvas) == 0;
+}
+FX_BOOL CFDE_VisualSetIterator::FilterObjects(FX_DWORD dwObjects )
+{
+ if (m_CanvasStack.GetSize() == 0) {
+ return FALSE;
+ }
+ while (m_CanvasStack.GetSize() > 1) {
+ m_CanvasStack.Pop();
+ }
+ m_dwFilter = dwObjects & ~(FX_DWORD)FDE_VISUALOBJ_Widget;
+ if (dwObjects & FDE_VISUALOBJ_Widget) {
+ m_dwFilter |= 0xFF00;
+ }
+ FDE_LPCANVASITEM pCanvas = m_CanvasStack.GetTopElement();
+ FXSYS_assert(pCanvas != NULL && pCanvas->pCanvas != NULL);
+ pCanvas->hPos = pCanvas->pCanvas->GetFirstPosition(NULL);
+ return pCanvas->hPos != NULL;
+}
+void CFDE_VisualSetIterator::Reset()
+{
+ FilterObjects(m_dwFilter);
+}
+FDE_HVISUALOBJ CFDE_VisualSetIterator::GetNext(IFDE_VisualSet *&pVisualSet, FDE_HVISUALOBJ *phCanvasObj , IFDE_CanvasSet **ppCanvasSet )
+{
+ while (m_CanvasStack.GetSize() > 0) {
+ FDE_LPCANVASITEM pCanvas = m_CanvasStack.GetTopElement();
+ FXSYS_assert(pCanvas != NULL && pCanvas->pCanvas != NULL);
+ if (pCanvas->hPos == NULL) {
+ if (m_CanvasStack.GetSize() == 1) {
+ break;
+ }
+ m_CanvasStack.Pop();
+ continue;
+ }
+ do {
+ FDE_HVISUALOBJ hObj = pCanvas->pCanvas->GetNext(pCanvas->hCanvas, pCanvas->hPos, pVisualSet);
+ FXSYS_assert(hObj != NULL);
+ FDE_VISUALOBJTYPE eType = pVisualSet->GetType();
+ if (eType == FDE_VISUALOBJ_Canvas) {
+ FDE_CANVASITEM canvas;
+ canvas.hCanvas = hObj;
+ canvas.pCanvas = (IFDE_CanvasSet*)pVisualSet;
+ canvas.hPos = canvas.pCanvas->GetFirstPosition(hObj);
+ m_CanvasStack.Push(canvas);
+ break;
+ }
+ FX_DWORD dwObj = (eType == FDE_VISUALOBJ_Widget)
+ ? (FX_DWORD)((IFDE_WidgetSet*)pVisualSet)->GetWidgetType(hObj)
+ : (FX_DWORD)eType;
+ if ((m_dwFilter & dwObj) != 0) {
+ if (ppCanvasSet) {
+ *ppCanvasSet = pCanvas->pCanvas;
+ }
+ if (phCanvasObj) {
+ *phCanvasObj = pCanvas->hCanvas;
+ }
+ return hObj;
+ }
+ } while (pCanvas->hPos != NULL);
+ }
+ if (ppCanvasSet) {
+ *ppCanvasSet = NULL;
+ }
+ if (phCanvasObj) {
+ *phCanvasObj = NULL;
+ }
+ pVisualSet = NULL;
+ return NULL;
+}
diff --git a/xfa/src/fdp/src/fde/fde_iterator.h b/xfa/src/fdp/src/fde/fde_iterator.h
new file mode 100644
index 0000000000..6ebd5c566f
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_iterator.h
@@ -0,0 +1,33 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_ITERATOR_IMP
+#define _FDE_ITERATOR_IMP
+typedef struct _FDE_CANVASITEM : public CFX_Target {
+ IFDE_CanvasSet *pCanvas;
+ FDE_HVISUALOBJ hCanvas;
+ FX_POSITION hPos;
+} FDE_CANVASITEM, * FDE_LPCANVASITEM;
+class CFDE_VisualSetIterator : public IFDE_VisualSetIterator, public CFX_Target
+{
+public:
+ CFDE_VisualSetIterator();
+ ~CFDE_VisualSetIterator();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_BOOL AttachCanvas(IFDE_CanvasSet *pCanvas);
+ virtual FX_BOOL FilterObjects(FX_DWORD dwObjects = 0xFFFFFFFF);
+
+ virtual void Reset();
+ virtual FDE_HVISUALOBJ GetNext(IFDE_VisualSet *&pVisualSet, FDE_HVISUALOBJ *phCanvasObj = NULL, IFDE_CanvasSet **ppCanvasSet = NULL);
+protected:
+ FX_DWORD m_dwFilter;
+ CFX_StackTemplate<FDE_CANVASITEM> m_CanvasStack;
+};
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_object.cpp b/xfa/src/fdp/src/fde/fde_object.cpp
new file mode 100644
index 0000000000..d8a555a7bd
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_object.cpp
@@ -0,0 +1,27 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_object.h"
+IFDE_Pen* IFDE_Pen::Create()
+{
+ return FDE_New CFDE_Pen();
+}
+IFDE_Brush* IFDE_Brush::Create(FX_INT32 iType)
+{
+ switch (iType) {
+ case FDE_BRUSHTYPE_Solid:
+ return FDE_New CFDE_SolidBrush;
+ case FDE_BRUSHTYPE_Hatch:
+ return FDE_New CFDE_HatchBrush;
+ case FDE_BRUSHTYPE_Texture:
+ return FDE_New CFDE_TextureBrush;
+ case FDE_BRUSHTYPE_LinearGradient:
+ return FDE_New CFDE_LinearBrush;
+ default:
+ return NULL;
+ }
+}
diff --git a/xfa/src/fdp/src/fde/fde_object.h b/xfa/src/fdp/src/fde/fde_object.h
new file mode 100644
index 0000000000..553d77fb21
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_object.h
@@ -0,0 +1,427 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_BASEOBJECT_IMP
+#define _FDE_BASEOBJECT_IMP
+class CFDE_Pen : public IFDE_Pen, public CFX_Target
+{
+public:
+ CFDE_Pen()
+ : m_Color(0)
+ , m_iLineCap(0)
+ , m_iLineJoin(0)
+ , m_iDashStyle(0)
+ , m_fDashPhase(0)
+ , m_fMiterLimit(10)
+ , m_bAutoRelease(FALSE)
+ , m_pBrush(NULL)
+ {
+ }
+
+ ~CFDE_Pen()
+ {
+ if (m_pBrush && m_bAutoRelease) {
+ m_pBrush->Release();
+ }
+ }
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+
+ virtual FX_INT32 GetType() const
+ {
+ return m_pBrush ? m_pBrush->GetType() : FDE_PENTYPE_SolidColor;
+ }
+
+ virtual FX_ARGB GetColor() const
+ {
+ return m_Color;
+ }
+ virtual void SetColor(FX_ARGB color)
+ {
+ m_Color = color;
+ }
+ virtual IFDE_Brush* GetBrush() const
+ {
+ return m_pBrush;
+ }
+ virtual void SetBrush(IFDE_Brush *pBrush, FX_BOOL bAutoRelease)
+ {
+ m_bAutoRelease = bAutoRelease;
+ m_pBrush = pBrush;
+ if (m_pBrush && m_pBrush->GetType() == FDE_BRUSHTYPE_Solid) {
+ m_Color = ((IFDE_SolidBrush*)m_pBrush)->GetColor();
+ }
+ }
+ virtual FX_INT32 GetLineCap() const
+ {
+ return m_iLineCap;
+ }
+ virtual void SetLineCap(FX_INT32 iLineCap)
+ {
+ m_iLineCap = iLineCap;
+ }
+ virtual FX_INT32 GetDashStyle() const
+ {
+ return m_iDashStyle;
+ }
+ virtual void SetDashStyle(FX_INT32 iDashStyle)
+ {
+ m_iDashStyle = iDashStyle;
+ }
+ virtual FX_FLOAT GetDashPhase() const
+ {
+ return m_fDashPhase;
+ }
+ virtual void SetDashPhase(FX_FLOAT fPhase)
+ {
+ m_fDashPhase = fPhase;
+ }
+ virtual FX_INT32 CountDashArray() const
+ {
+ return m_DashArray.GetSize();
+ }
+ virtual FX_INT32 GetDashArray(CFX_FloatArray &dashArray) const
+ {
+ dashArray.Copy(m_DashArray);
+ return dashArray.GetSize();
+ }
+ virtual void SetDashArray(const CFX_FloatArray &dashArray)
+ {
+ m_DashArray.Copy(dashArray);
+ }
+ virtual FX_INT32 GetLineJoin() const
+ {
+ return m_iLineJoin;
+ }
+ virtual void SetLineJoin(FX_INT32 iLineJoin)
+ {
+ m_iLineJoin = iLineJoin;
+ }
+ virtual FX_FLOAT GetMiterLimit() const
+ {
+ return m_fMiterLimit;
+ }
+ virtual void SetMiterLimit(FX_FLOAT fMiterLimit)
+ {
+ m_fMiterLimit = fMiterLimit;
+ }
+ virtual FX_INT32 CountCompoundPatterns() const
+ {
+ return m_CompoundPatterns.GetSize();
+ }
+ virtual FX_BOOL GetCompoundPatterns(CFDE_CompoundPatterns &compoundPatterns) const
+ {
+ return compoundPatterns.Copy(m_CompoundPatterns), TRUE;
+ }
+ virtual FX_BOOL SetCompoundPatterns(const CFDE_CompoundPatterns &compoundPatterns)
+ {
+ return m_CompoundPatterns.Copy(compoundPatterns), TRUE;
+ }
+
+ FX_ARGB m_Color;
+ FX_INT32 m_iLineCap;
+ FX_INT32 m_iLineJoin;
+ FX_INT32 m_iDashStyle;
+ FX_FLOAT m_fDashPhase;
+ FX_FLOAT m_fMiterLimit;
+ FX_BOOL m_bAutoRelease;
+ IFDE_Brush *m_pBrush;
+ CFX_FloatArray m_DashArray;
+ CFDE_CompoundPatterns m_CompoundPatterns;
+};
+class CFDE_SolidBrush : public IFDE_SolidBrush, public CFX_Target
+{
+public:
+ CFDE_SolidBrush() : m_Color(0xFF000000)
+ {
+ m_Matrix.Reset();
+ }
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 GetType() const
+ {
+ return FDE_BRUSHTYPE_Solid;
+ }
+ virtual const CFX_Matrix& GetMatrix() const
+ {
+ return m_Matrix;
+ }
+ virtual void ResetMatrix()
+ {
+ m_Matrix.Reset();
+ }
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy)
+ {
+ m_Matrix.Translate(dx, dy);
+ }
+ virtual void RotateMatrix(FX_FLOAT fRadian)
+ {
+ m_Matrix.Rotate(fRadian);
+ }
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy)
+ {
+ m_Matrix.Scale(sx, sy);
+ }
+ virtual void ConcatMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix.Concat(matrix);
+ }
+ virtual void SetMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix = matrix;
+ }
+ virtual FX_ARGB GetColor() const
+ {
+ return m_Color;
+ }
+ virtual void SetColor(FX_ARGB color)
+ {
+ m_Color = color;
+ }
+
+ FX_ARGB m_Color;
+ CFX_Matrix m_Matrix;
+};
+class CFDE_HatchBrush : public IFDE_HatchBrush, public CFX_Target
+{
+public:
+ CFDE_HatchBrush() : m_iStyle(-1), m_BackColor(0), m_ForeColor(0)
+ {
+ m_Matrix.Reset();
+ }
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 GetType() const
+ {
+ return FDE_BRUSHTYPE_Hatch;
+ }
+ virtual const CFX_Matrix& GetMatrix() const
+ {
+ return m_Matrix;
+ }
+ virtual void ResetMatrix()
+ {
+ m_Matrix.Reset();
+ }
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy)
+ {
+ m_Matrix.Translate(dx, dy);
+ }
+ virtual void RotateMatrix(FX_FLOAT fRadian)
+ {
+ m_Matrix.Rotate(fRadian);
+ }
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy)
+ {
+ m_Matrix.Scale(sx, sy);
+ }
+ virtual void ConcatMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix.Concat(matrix);
+ }
+ virtual void SetMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix = matrix;
+ }
+ virtual FX_ARGB GetColor(FX_BOOL bForegroundColor) const
+ {
+ return bForegroundColor ? m_ForeColor : m_BackColor;
+ }
+ virtual void SetColor(FX_ARGB color, FX_BOOL bForegroundColor)
+ {
+ if (bForegroundColor) {
+ m_ForeColor = color;
+ } else {
+ m_BackColor = color;
+ }
+ }
+
+ virtual FX_INT32 GetHatchStyle() const
+ {
+ return m_iStyle;
+ };
+ virtual FX_BOOL SetHatchStyle(FX_INT32 iHatchStyle)
+ {
+ m_iStyle = iHatchStyle;
+ return m_iStyle >= FDE_HATCHSTYLE_Min && m_iStyle <= FDE_HATCHSTYLE_Max;
+ }
+ FX_INT32 m_iStyle;
+ FX_ARGB m_BackColor;
+ FX_ARGB m_ForeColor;
+ CFX_Matrix m_Matrix;
+};
+class CFDE_TextureBrush : public IFDE_TextureBrush, public CFX_Target
+{
+public:
+ CFDE_TextureBrush()
+ : m_iWrap(0)
+ , m_pImage(NULL)
+ , m_bAutoRelease(FALSE)
+ {
+ m_Matrix.Reset();
+ }
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 GetType() const
+ {
+ return FDE_BRUSHTYPE_Texture;
+ }
+ virtual const CFX_Matrix& GetMatrix() const
+ {
+ return m_Matrix;
+ }
+ virtual void ResetMatrix()
+ {
+ m_Matrix.Reset();
+ }
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy)
+ {
+ m_Matrix.Translate(dx, dy);
+ }
+ virtual void RotateMatrix(FX_FLOAT fRadian)
+ {
+ m_Matrix.Rotate(fRadian);
+ }
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy)
+ {
+ m_Matrix.Scale(sx, sy);
+ }
+ virtual void ConcatMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix.Concat(matrix);
+ }
+ virtual void SetMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix = matrix;
+ }
+ virtual IFDE_Image* GetImage() const
+ {
+ return m_pImage;
+ }
+ virtual void SetImage(IFDE_Image *pImage, FX_BOOL bAutoRelease)
+ {
+ m_pImage = pImage;
+ m_bAutoRelease = bAutoRelease;
+ }
+ virtual FX_INT32 GetWrapMode() const
+ {
+ return m_iWrap;
+ }
+ virtual void SetWrapMode(FX_INT32 iWrapMode)
+ {
+ m_iWrap = iWrapMode;
+ }
+ FX_INT32 m_iWrap;
+ IFDE_Image *m_pImage;
+ FX_BOOL m_bAutoRelease;
+ CFX_Matrix m_Matrix;
+};
+class CFDE_LinearBrush : public IFDE_LinearGradientBrush, public CFX_Target
+{
+public:
+ CFDE_LinearBrush() : m_EndColor(0), m_StartColor(0), m_iWrapMode(0)
+ {
+ m_StartPoint.x = m_StartPoint.y = m_EndPoint.x = m_EndPoint.y = 0;
+ m_Matrix.Reset();
+ }
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 GetType() const
+ {
+ return FDE_BRUSHTYPE_LinearGradient;
+ }
+ virtual const CFX_Matrix& GetMatrix() const
+ {
+ return m_Matrix;
+ }
+ virtual void ResetMatrix()
+ {
+ m_Matrix.Reset();
+ }
+ virtual void TranslateMatrix(FX_FLOAT dx, FX_FLOAT dy)
+ {
+ m_Matrix.Translate(dx, dy);
+ }
+ virtual void RotateMatrix(FX_FLOAT fRadian)
+ {
+ m_Matrix.Rotate(fRadian);
+ }
+ virtual void ScaleMatrix(FX_FLOAT sx, FX_FLOAT sy)
+ {
+ m_Matrix.Scale(sx, sy);
+ }
+ virtual void ConcatMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix.Concat(matrix);
+ }
+ virtual void SetMatrix(const CFX_Matrix &matrix)
+ {
+ m_Matrix = matrix;
+ }
+ virtual void GetLinearPoints(CFX_PointF &startingPoint, CFX_PointF &endingPoint) const
+ {
+ startingPoint = m_StartPoint;
+ endingPoint = m_EndPoint;
+ }
+ virtual void SetLinearPoints(const CFX_PointF &startingPoint, const CFX_PointF &endingPoint)
+ {
+ m_StartPoint = startingPoint;
+ m_EndPoint = endingPoint;
+ }
+ virtual void GetLinearColors(FX_ARGB &startingColor, FX_ARGB &endingColor) const
+ {
+ startingColor = m_StartColor;
+ endingColor = m_EndColor;
+ }
+ virtual void SetLinearColors(const FX_ARGB &startingColor, const FX_ARGB &endingColor)
+ {
+ m_StartColor = startingColor;
+ m_EndColor = endingColor;
+ }
+ virtual FX_INT32 CountGradientColors() const
+ {
+ return m_GradColors.GetSize();
+ }
+ virtual FX_BOOL GetGradientColors(CFDE_GradientColors &colors) const
+ {
+ return colors.Copy(m_GradColors), TRUE;
+ }
+ virtual FX_BOOL SetGradientColors(const CFDE_GradientColors &colors)
+ {
+ return m_GradColors.Copy(colors), TRUE;
+ }
+
+ virtual FX_INT32 GetWrapMode() const
+ {
+ return m_iWrapMode;
+ }
+ virtual void SetWrapMode(FX_INT32 iWrapMode)
+ {
+ m_iWrapMode = iWrapMode;
+ }
+ CFX_PointF m_EndPoint;
+ CFX_PointF m_StartPoint;
+ FX_ARGB m_EndColor;
+ FX_ARGB m_StartColor;
+ CFDE_GradientColors m_GradColors;
+ FX_INT32 m_iWrapMode;
+ CFX_Matrix m_Matrix;
+};
+#endif
diff --git a/xfa/src/fdp/src/fde/fde_render.cpp b/xfa/src/fdp/src/fde/fde_render.cpp
new file mode 100644
index 0000000000..e8e9149e02
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_render.cpp
@@ -0,0 +1,253 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_render.h"
+void FDE_GetPageMatrix(CFX_Matrix &pageMatrix, const CFX_RectF &docPageRect, const CFX_Rect &devicePageRect, FX_INT32 iRotate, FX_DWORD dwCoordinatesType)
+{
+ FXSYS_assert(iRotate >= 0 && iRotate <= 3);
+ FX_BOOL bFlipX = (dwCoordinatesType & 0x01) != 0;
+ FX_BOOL bFlipY = (dwCoordinatesType & 0x02) != 0;
+ CFX_Matrix m;
+ m.Set((bFlipX ? -1.0f : 1.0f), 0, 0, (bFlipY ? -1.0f : 1.0f), 0, 0);
+ if (iRotate == 0 || iRotate == 2) {
+ m.a *= (FX_FLOAT)devicePageRect.width / docPageRect.width;
+ m.d *= (FX_FLOAT)devicePageRect.height / docPageRect.height;
+ } else {
+ m.a *= (FX_FLOAT)devicePageRect.height / docPageRect.width;
+ m.d *= (FX_FLOAT)devicePageRect.width / docPageRect.height;
+ }
+ m.Rotate(iRotate * 1.57079632675f);
+ switch (iRotate) {
+ case 0:
+ m.e = bFlipX ? (FX_FLOAT)devicePageRect.right() : (FX_FLOAT)devicePageRect.left;
+ m.f = bFlipY ? (FX_FLOAT)devicePageRect.bottom() : (FX_FLOAT)devicePageRect.top;
+ break;
+ case 1:
+ m.e = bFlipY ? (FX_FLOAT)devicePageRect.left : (FX_FLOAT)devicePageRect.right();
+ m.f = bFlipX ? (FX_FLOAT)devicePageRect.bottom() : (FX_FLOAT)devicePageRect.top;
+ break;
+ case 2:
+ m.e = bFlipX ? (FX_FLOAT)devicePageRect.left : (FX_FLOAT)devicePageRect.right();
+ m.f = bFlipY ? (FX_FLOAT)devicePageRect.top : (FX_FLOAT)devicePageRect.bottom();
+ break;
+ case 3:
+ m.e = bFlipY ? (FX_FLOAT)devicePageRect.right() : (FX_FLOAT)devicePageRect.left;
+ m.f = bFlipX ? (FX_FLOAT)devicePageRect.top : (FX_FLOAT)devicePageRect.bottom();
+ break;
+ default:
+ break;
+ }
+ pageMatrix = m;
+}
+IFDE_RenderContext* IFDE_RenderContext::Create()
+{
+ return FDE_New CFDE_RenderContext;
+}
+CFDE_RenderContext::CFDE_RenderContext()
+ : CFX_ThreadLock()
+ , m_eStatus(FDE_RENDERSTATUS_Reset)
+ , m_pRenderDevice(NULL)
+ , m_pSolidBrush(NULL)
+ , m_Transform()
+ , m_pCharPos(NULL)
+ , m_iCharPosCount(0)
+ , m_pIterator(NULL)
+{
+ m_Transform.Reset();
+}
+CFDE_RenderContext::~CFDE_RenderContext()
+{
+ StopRender();
+}
+FX_BOOL CFDE_RenderContext::StartRender(IFDE_RenderDevice *pRenderDevice, IFDE_CanvasSet *pCanvasSet, const CFX_Matrix &tmDoc2Device )
+{
+ if (m_pRenderDevice != NULL) {
+ return FALSE;
+ }
+ if (pRenderDevice == NULL) {
+ return FALSE;
+ }
+ if (pCanvasSet == NULL) {
+ return FALSE;
+ }
+ Lock();
+ m_eStatus = FDE_RENDERSTATUS_Paused;
+ m_pRenderDevice = pRenderDevice;
+ m_Transform = tmDoc2Device;
+ if (m_pIterator == NULL) {
+ m_pIterator = IFDE_VisualSetIterator::Create();
+ FXSYS_assert(m_pIterator != NULL);
+ }
+ FX_BOOL bAttach = m_pIterator->AttachCanvas(pCanvasSet) && m_pIterator->FilterObjects();
+ Unlock();
+ return bAttach;
+}
+FDE_RENDERSTATUS CFDE_RenderContext::DoRender(IFX_Pause *pPause)
+{
+ if (m_pRenderDevice == NULL) {
+ return FDE_RENDERSTATUS_Failed;
+ }
+ if (m_pIterator == NULL) {
+ return FDE_RENDERSTATUS_Failed;
+ }
+ Lock();
+ FDE_RENDERSTATUS eStatus = FDE_RENDERSTATUS_Paused;
+ CFX_Matrix rm;
+ rm.SetReverse(m_Transform);
+ CFX_RectF rtDocClip = m_pRenderDevice->GetClipRect();
+ if (rtDocClip.IsEmpty()) {
+ rtDocClip.left = rtDocClip.top = 0;
+ rtDocClip.width = (FX_FLOAT)m_pRenderDevice->GetWidth();
+ rtDocClip.height = (FX_FLOAT)m_pRenderDevice->GetHeight();
+ }
+ rm.TransformRect(rtDocClip);
+ IFDE_VisualSet *pVisualSet;
+ FDE_HVISUALOBJ hVisualObj;
+ CFX_RectF rtObj;
+ FX_INT32 iCount = 0;
+ while(TRUE) {
+ hVisualObj = m_pIterator->GetNext(pVisualSet);
+ if (hVisualObj == NULL || pVisualSet == NULL) {
+ eStatus = FDE_RENDERSTATUS_Done;
+ break;
+ }
+ rtObj.Empty();
+ pVisualSet->GetRect(hVisualObj, rtObj);
+ if (!rtDocClip.IntersectWith(rtObj)) {
+ continue;
+ }
+ switch (pVisualSet->GetType()) {
+ case FDE_VISUALOBJ_Text:
+ RenderText((IFDE_TextSet*)pVisualSet, hVisualObj);
+ iCount += 5;
+ break;
+ case FDE_VISUALOBJ_Path:
+ RenderPath((IFDE_PathSet*)pVisualSet, hVisualObj);
+ iCount += 20;
+ break;
+ case FDE_VISUALOBJ_Widget:
+ iCount += 10;
+ break;
+ case FDE_VISUALOBJ_Canvas:
+ FXSYS_assert(FALSE);
+ break;
+ default:
+ break;
+ }
+ if (iCount >= 100 && pPause != NULL && pPause->NeedToPauseNow()) {
+ eStatus = FDE_RENDERSTATUS_Paused;
+ break;
+ }
+ }
+ Unlock();
+ return m_eStatus = eStatus;
+}
+void CFDE_RenderContext::StopRender()
+{
+ Lock();
+ m_eStatus = FDE_RENDERSTATUS_Reset;
+ m_pRenderDevice = NULL;
+ m_Transform.Reset();
+ if (m_pIterator != NULL) {
+ m_pIterator->Release();
+ m_pIterator = NULL;
+ }
+ if (m_pSolidBrush != NULL) {
+ m_pSolidBrush->Release();
+ m_pSolidBrush = NULL;
+ }
+ if (m_pCharPos != NULL) {
+ FDE_Free(m_pCharPos);
+ m_pCharPos = NULL;
+ }
+ m_iCharPosCount = 0;
+ Unlock();
+}
+void CFDE_RenderContext::RenderText(IFDE_TextSet *pTextSet, FDE_HVISUALOBJ hText)
+{
+ FXSYS_assert(m_pRenderDevice != NULL);
+ FXSYS_assert(pTextSet != NULL && hText != NULL);
+ IFX_Font *pFont = pTextSet->GetFont(hText);
+ if (pFont == NULL) {
+ return;
+ }
+ FX_INT32 iCount = pTextSet->GetDisplayPos(hText, NULL, FALSE);
+ if (iCount < 1) {
+ return;
+ }
+ if (m_pSolidBrush == NULL) {
+ m_pSolidBrush = (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid);
+ if (m_pSolidBrush == NULL) {
+ return;
+ }
+ }
+ if (m_pCharPos == NULL) {
+ m_pCharPos = (FXTEXT_CHARPOS*)FDE_Alloc(sizeof(FXTEXT_CHARPOS) * iCount);
+ } else if (m_iCharPosCount < iCount) {
+ m_pCharPos = (FXTEXT_CHARPOS*)FDE_Realloc(m_pCharPos, sizeof(FXTEXT_CHARPOS) * iCount);
+ }
+ if (m_iCharPosCount < iCount) {
+ m_iCharPosCount = iCount;
+ }
+ iCount = pTextSet->GetDisplayPos(hText, m_pCharPos, FALSE);
+ FX_FLOAT fFontSize = pTextSet->GetFontSize(hText);
+ FX_ARGB dwColor = pTextSet->GetFontColor(hText);
+ m_pSolidBrush->SetColor(dwColor);
+ FDE_HDEVICESTATE hState;
+ FX_BOOL bClip = ApplyClip(pTextSet, hText, hState);
+ m_pRenderDevice->DrawString(m_pSolidBrush, pFont, m_pCharPos, iCount, fFontSize, &m_Transform);
+ if (bClip) {
+ RestoreClip(hState);
+ }
+}
+void CFDE_RenderContext::RenderPath(IFDE_PathSet *pPathSet, FDE_HVISUALOBJ hPath)
+{
+ FXSYS_assert(m_pRenderDevice != NULL);
+ FXSYS_assert(pPathSet != NULL && hPath != NULL);
+ IFDE_Path *pPath = pPathSet->GetPath(hPath);
+ if (pPath == NULL) {
+ return;
+ }
+ FDE_HDEVICESTATE hState;
+ FX_BOOL bClip = ApplyClip(pPathSet, hPath, hState);
+ FX_INT32 iRenderMode = pPathSet->GetRenderMode(hPath);
+ if (iRenderMode & FDE_PATHRENDER_Stroke) {
+ IFDE_Pen *pPen = pPathSet->GetPen(hPath);
+ FX_FLOAT fWidth = pPathSet->GetPenWidth(hPath);
+ if (pPen != NULL && fWidth > 0) {
+ m_pRenderDevice->DrawPath(pPen, fWidth, pPath, &m_Transform);
+ }
+ }
+ if (iRenderMode & FDE_PATHRENDER_Fill) {
+ IFDE_Brush *pBrush = pPathSet->GetBrush(hPath);
+ if (pBrush != NULL) {
+ m_pRenderDevice->FillPath(pBrush, pPath, &m_Transform);
+ }
+ }
+ if (bClip) {
+ RestoreClip(hState);
+ }
+}
+FX_BOOL CFDE_RenderContext::ApplyClip(IFDE_VisualSet *pVisualSet, FDE_HVISUALOBJ hObj, FDE_HDEVICESTATE &hState)
+{
+ CFX_RectF rtClip;
+ if (!pVisualSet->GetClip(hObj, rtClip)) {
+ return FALSE;
+ }
+ CFX_RectF rtObj;
+ pVisualSet->GetRect(hObj, rtObj);
+ rtClip.Offset(rtObj.left, rtObj.top);
+ m_Transform.TransformRect(rtClip);
+ const CFX_RectF &rtDevClip = m_pRenderDevice->GetClipRect();
+ rtClip.Intersect(rtDevClip);
+ hState = m_pRenderDevice->SaveState();
+ return m_pRenderDevice->SetClipRect(rtClip);
+}
+void CFDE_RenderContext::RestoreClip(FDE_HDEVICESTATE hState)
+{
+ m_pRenderDevice->RestoreState(hState);
+}
diff --git a/xfa/src/fdp/src/fde/fde_render.h b/xfa/src/fdp/src/fde/fde_render.h
new file mode 100644
index 0000000000..909987a032
--- /dev/null
+++ b/xfa/src/fdp/src/fde/fde_render.h
@@ -0,0 +1,42 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_RENDER_IMP
+#define _FDE_RENDER_IMP
+class CFDE_RenderContext;
+class CFDE_RenderContext : public IFDE_RenderContext, public CFX_ThreadLock, public CFX_Target
+{
+public:
+ CFDE_RenderContext();
+ virtual ~CFDE_RenderContext();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_BOOL StartRender(IFDE_RenderDevice *pRenderDevice,
+ IFDE_CanvasSet *pCanvasSet,
+ const CFX_Matrix &tmDoc2Device
+ );
+ virtual FDE_RENDERSTATUS GetStatus() const
+ {
+ return m_eStatus;
+ }
+ virtual FDE_RENDERSTATUS DoRender(IFX_Pause *pPause = NULL);
+ virtual void StopRender();
+ void RenderPath(IFDE_PathSet *pPathSet, FDE_HVISUALOBJ hPath);
+ void RenderText(IFDE_TextSet *pTextSet, FDE_HVISUALOBJ hText);
+ FX_BOOL ApplyClip(IFDE_VisualSet *pVisualSet, FDE_HVISUALOBJ hObj, FDE_HDEVICESTATE &hState);
+ void RestoreClip(FDE_HDEVICESTATE hState);
+protected:
+ FDE_RENDERSTATUS m_eStatus;
+ IFDE_RenderDevice *m_pRenderDevice;
+ IFDE_SolidBrush *m_pSolidBrush;
+ CFX_Matrix m_Transform;
+ FXTEXT_CHARPOS *m_pCharPos;
+ FX_INT32 m_iCharPosCount;
+ IFDE_VisualSetIterator *m_pIterator;
+};
+#endif
diff --git a/xfa/src/fdp/src/tto/fde_textout.cpp b/xfa/src/fdp/src/tto/fde_textout.cpp
new file mode 100644
index 0000000000..e03620244f
--- /dev/null
+++ b/xfa/src/fdp/src/tto/fde_textout.cpp
@@ -0,0 +1,952 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_textout.h"
+IFDE_TextOut* IFDE_TextOut::Create()
+{
+ return FDE_New CFDE_TextOut;
+}
+CFDE_TextOut::CFDE_TextOut()
+ : m_pFont(NULL)
+ , m_fFontSize(12.0f)
+ , m_fLineSpace(m_fFontSize)
+ , m_fLinePos(0.0f)
+ , m_fTolerance(0.0f)
+ , m_iAlignment(0)
+ , m_iTxtBkAlignment(0)
+ , m_pCharWidths(NULL)
+ , m_iChars(0)
+ , m_pEllCharWidths(NULL)
+ , m_iEllChars(0)
+ , m_wParagraphBkChar(L'\n')
+ , m_TxtColor(0xFF000000)
+ , m_dwStyles(0)
+ , m_dwTxtBkStyles(0)
+ , m_bElliChanged(FALSE)
+ , m_iEllipsisWidth(0)
+ , m_ttoLines(5)
+ , m_iCurLine(0)
+ , m_iTotalLines(0)
+ , m_iCurPiece(0)
+ , m_pCharPos(NULL)
+ , m_iCharPosSize(0)
+ , m_pRenderDevice(NULL)
+{
+ m_pTxtBreak = IFX_TxtBreak::Create(FX_TXTBREAKPOLICY_None);
+ FXSYS_assert(m_pTxtBreak != NULL);
+ m_Matrix.Reset();
+ m_rtClip.Reset();
+ m_rtLogicClip.Reset();
+}
+CFDE_TextOut::~CFDE_TextOut()
+{
+ if (m_pTxtBreak != NULL) {
+ m_pTxtBreak->Release();
+ }
+ if (m_pCharWidths != NULL) {
+ FDE_Free(m_pCharWidths);
+ }
+ if (m_pEllCharWidths != NULL) {
+ FDE_Free(m_pEllCharWidths);
+ }
+ if (m_pRenderDevice != NULL) {
+ m_pRenderDevice->Release();
+ }
+ if (m_pCharPos != NULL) {
+ FDE_Free(m_pCharPos);
+ }
+ m_ttoLines.RemoveAll();
+}
+void CFDE_TextOut::SetFont(IFX_Font *pFont)
+{
+ FXSYS_assert(pFont != NULL);
+ m_pFont = pFont;
+ m_pTxtBreak->SetFont(pFont);
+}
+void CFDE_TextOut::SetFontSize(FX_FLOAT fFontSize)
+{
+ FXSYS_assert(fFontSize > 0);
+ m_fFontSize = fFontSize;
+ m_pTxtBreak->SetFontSize(fFontSize);
+}
+void CFDE_TextOut::SetTextColor(FX_ARGB color)
+{
+ m_TxtColor = color;
+}
+void CFDE_TextOut::SetStyles(FX_DWORD dwStyles)
+{
+ m_dwStyles = dwStyles;
+ m_dwTxtBkStyles = 0;
+ if (dwStyles & FDE_TTOSTYLE_SingleLine) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_SingleLine;
+ }
+ if (dwStyles & FDE_TTOSTYLE_ExpandTab) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_ExpandTab;
+ }
+ if (dwStyles & FDE_TTOSTYLE_ArabicShapes) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_ArabicShapes;
+ }
+ if (dwStyles & FDE_TTOSTYLE_RTL) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_RTLReadingOrder;
+ }
+ if (dwStyles & FDE_TTOSTYLE_ArabicContext) {
+ m_dwTxtBkStyles |= FX_TXTLAYOUTSTYLE_ArabicContext;
+ }
+ if (dwStyles & FDE_TTOSTYLE_VerticalLayout) {
+ m_dwTxtBkStyles |= (FX_TXTLAYOUTSTYLE_VerticalChars | FX_TXTLAYOUTSTYLE_VerticalLayout);
+ }
+ m_pTxtBreak->SetLayoutStyles(m_dwTxtBkStyles);
+}
+void CFDE_TextOut::SetTabWidth(FX_FLOAT fTabWidth)
+{
+ FXSYS_assert(fTabWidth > 1.0f);
+ m_pTxtBreak->SetTabWidth(fTabWidth, FALSE);
+}
+void CFDE_TextOut::SetEllipsisString(const CFX_WideString &wsEllipsis)
+{
+ m_bElliChanged = TRUE;
+ m_wsEllipsis = wsEllipsis;
+}
+void CFDE_TextOut::SetParagraphBreakChar(FX_WCHAR wch)
+{
+ m_wParagraphBkChar = wch;
+ m_pTxtBreak->SetParagraphBreakChar(wch);
+}
+void CFDE_TextOut::SetAlignment(FX_INT32 iAlignment)
+{
+ m_iAlignment = iAlignment;
+ switch (m_iAlignment) {
+ case FDE_TTOALIGNMENT_TopCenter:
+ case FDE_TTOALIGNMENT_Center:
+ case FDE_TTOALIGNMENT_BottomCenter:
+ m_iTxtBkAlignment = FX_TXTLINEALIGNMENT_Center;
+ break;
+ case FDE_TTOALIGNMENT_TopRight:
+ case FDE_TTOALIGNMENT_CenterRight:
+ case FDE_TTOALIGNMENT_BottomRight:
+ m_iTxtBkAlignment = FX_TXTLINEALIGNMENT_Right;
+ break;
+ default:
+ m_iTxtBkAlignment = FX_TXTLINEALIGNMENT_Left;
+ break;
+ }
+ m_pTxtBreak->SetAlignment(m_iTxtBkAlignment);
+}
+void CFDE_TextOut::SetLineSpace(FX_FLOAT fLineSpace)
+{
+ FXSYS_assert(fLineSpace > 1.0f);
+ m_fLineSpace = fLineSpace;
+}
+void CFDE_TextOut::SetDIBitmap(CFX_DIBitmap *pDIB)
+{
+ FXSYS_assert(pDIB != NULL);
+ if (m_pRenderDevice != NULL) {
+ m_pRenderDevice->Release();
+ }
+ m_pRenderDevice = IFDE_RenderDevice::Create(pDIB);
+}
+void CFDE_TextOut::SetRenderDevice(CFX_RenderDevice *pDevice)
+{
+ FXSYS_assert(pDevice != NULL);
+ if (m_pRenderDevice != NULL) {
+ m_pRenderDevice->Release();
+ }
+ m_pRenderDevice = IFDE_RenderDevice::Create(pDevice);
+}
+void CFDE_TextOut::SetClipRect(const CFX_Rect &rtClip)
+{
+ m_rtClip.Set((FX_FLOAT)rtClip.left, (FX_FLOAT)rtClip.top, (FX_FLOAT)rtClip.Width(), (FX_FLOAT)rtClip.Height());
+}
+void CFDE_TextOut::SetClipRect(const CFX_RectF &rtClip)
+{
+ m_rtClip = rtClip;
+}
+void CFDE_TextOut::SetLogicClipRect(const CFX_RectF &rtClip)
+{
+ m_rtLogicClip = rtClip;
+}
+void CFDE_TextOut::SetMatrix(const CFX_Matrix &matrix)
+{
+ m_Matrix = matrix;
+}
+void CFDE_TextOut::SetLineBreakTolerance(FX_FLOAT fTolerance)
+{
+ m_fTolerance = fTolerance;
+ m_pTxtBreak->SetLineBreakTolerance(m_fTolerance);
+}
+FX_INT32 CFDE_TextOut::GetTotalLines()
+{
+ return m_iTotalLines;
+}
+void CFDE_TextOut::CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Size &size)
+{
+ CFX_RectF rtText;
+ rtText.Set(0.0f, 0.0f, (FX_FLOAT)size.x, (FX_FLOAT)size.y);
+ CalcSize(pwsStr, iLength, rtText);
+ size.x = (FX_INT32)rtText.Width();
+ size.y = (FX_INT32)rtText.Height();
+}
+void CFDE_TextOut::CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size)
+{
+ CFX_RectF rtText;
+ rtText.Set(0.0f, 0.0f, size.x, size.y);
+ CalcSize(pwsStr, iLength, rtText);
+ size.x = rtText.Width();
+ size.y = rtText.Height();
+}
+void CFDE_TextOut::CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Rect &rect)
+{
+ CFX_RectF rtText;
+ rtText.Set((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, (FX_FLOAT)rect.Width(), (FX_FLOAT)rect.Height());
+ CalcSize(pwsStr, iLength, rtText);
+ rect.Set((FX_INT32)rtText.left, (FX_INT32)rtText.top, (FX_INT32)rtText.Width(), (FX_INT32)rtText.Height());
+}
+void CFDE_TextOut::CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect)
+{
+ if (pwsStr == NULL || iLength < 1) {
+ rect.width = 0.0f;
+ rect.height = 0.0f;
+ } else {
+ CFX_Matrix rm;
+ rm.SetReverse(m_Matrix);
+ rm.TransformRect(rect);
+ CalcTextSize(pwsStr, iLength, rect);
+ m_Matrix.TransformRect(rect);
+ }
+}
+void CFDE_TextOut::CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size)
+{
+ CFX_RectF rtText;
+ rtText.Set(0.0f, 0.0f, size.x, size.y);
+ CalcLogicSize(pwsStr, iLength, rtText);
+ size.x = rtText.Width();
+ size.y = rtText.Height();
+}
+void CFDE_TextOut::CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect)
+{
+ if (pwsStr == NULL || iLength < 1) {
+ rect.width = 0.0f;
+ rect.height = 0.0f;
+ } else {
+ CalcTextSize(pwsStr, iLength, rect);
+ }
+}
+void CFDE_TextOut::CalcTextSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect)
+{
+ FXSYS_assert(m_pFont != NULL && m_fFontSize >= 1.0f);
+ SetLineWidth(rect);
+ m_iTotalLines = 0;
+ FX_LPCWSTR pStr = pwsStr;
+ FX_BOOL bHotKey = (m_dwStyles & FDE_TTOSTYLE_HotKey) ? TRUE : FALSE;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_FLOAT fWidth = 0.0f;
+ FX_FLOAT fHeight = 0.0f;
+ FX_FLOAT fStartPos = bVertical ? rect.bottom() : rect.right();
+ FX_DWORD dwBreakStatus = 0;
+ FX_WCHAR wPreChar = 0;
+ FX_WCHAR wch;
+ FX_WCHAR wBreak = 0;
+ while (iLength-- > 0) {
+ wch = *pStr++;
+ if (wBreak == 0 && (wch == L'\n' || wch == L'\r')) {
+ wBreak = wch;
+ m_pTxtBreak->SetParagraphBreakChar(wch);
+ }
+ if (bHotKey && wch == L'&' && wPreChar != L'&') {
+ wPreChar = wch;
+ continue;
+ }
+ dwBreakStatus = m_pTxtBreak->AppendChar(wch);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight);
+ }
+ wPreChar = 0;
+ }
+ dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetrieveLineWidth(dwBreakStatus, fStartPos, fWidth, fHeight);
+ }
+ m_pTxtBreak->Reset();
+ FX_FLOAT fInc = rect.Height() - fHeight;
+ if (bVertical) {
+ fInc = rect.Width() - fHeight;
+ }
+ if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft && m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) {
+ fInc /= 2.0f;
+ } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) {
+ fInc = 0.0f;
+ }
+ if (bVertical) {
+ rect.top += fStartPos;
+ rect.left += fInc;
+ rect.width = fHeight;
+ rect.height = FX_MIN(fWidth, rect.Height());
+ } else {
+ rect.left += fStartPos;
+ rect.top += fInc;
+ rect.width = FX_MIN(fWidth, rect.Width());
+ rect.height = fHeight;
+ if (m_dwStyles & FDE_TTOSTYLE_LastLineHeight) {
+ rect.height -= m_fLineSpace - m_fFontSize;
+ }
+ }
+}
+void CFDE_TextOut::SetLineWidth(CFX_RectF &rect)
+{
+ if ((m_dwStyles & FDE_TTOSTYLE_SingleLine) == 0) {
+ FX_FLOAT fLineWidth = 0.0f;
+ if (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) {
+ if (rect.Height() < 1.0f) {
+ rect.height = m_fFontSize * 1000.0f;
+ }
+ fLineWidth = rect.Height();
+ } else {
+ if (rect.Width() < 1.0f) {
+ rect.width = m_fFontSize * 1000.0f;
+ }
+ fLineWidth = rect.Width();
+ }
+ m_pTxtBreak->SetLineWidth(fLineWidth);
+ }
+}
+FX_BOOL CFDE_TextOut::RetrieveLineWidth(FX_DWORD dwBreakStatus, FX_FLOAT &fStartPos, FX_FLOAT &fWidth, FX_FLOAT &fHeight)
+{
+ if (dwBreakStatus <= FX_TXTBREAK_PieceBreak) {
+ return FALSE;
+ }
+ FX_FLOAT fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
+ FX_BOOL bLineWrap = (m_dwStyles & FDE_TTOSTYLE_LineWrap) ? TRUE : FALSE;
+ FX_FLOAT fLineWidth = 0.0f;
+ FX_INT32 iCount = m_pTxtBreak->CountBreakPieces();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ const CFX_TxtPiece *pPiece = m_pTxtBreak->GetBreakPiece(i);
+ fLineWidth += (FX_FLOAT)pPiece->m_iWidth / 20000.0f;
+ fStartPos = FX_MIN(fStartPos, (FX_FLOAT)pPiece->m_iStartPos / 20000.0f);
+ }
+ m_pTxtBreak->ClearBreakPieces();
+ if (dwBreakStatus == FX_TXTBREAK_ParagraphBreak) {
+ m_pTxtBreak->Reset();
+ }
+ if (!bLineWrap && dwBreakStatus == FX_TXTBREAK_LineBreak) {
+ fWidth += fLineWidth;
+ } else {
+ fWidth = FX_MAX(fWidth, fLineWidth);
+ fHeight += fLineStep;
+ }
+ m_iTotalLines++;
+ return TRUE;
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_INT32 x, FX_INT32 y)
+{
+ CFX_RectF rtText;
+ rtText.Set((FX_FLOAT)x, (FX_FLOAT)y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f);
+ DrawText(pwsStr, iLength, rtText);
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y)
+{
+ CFX_RectF rtText;
+ rtText.Set(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f);
+ DrawText(pwsStr, iLength, rtText);
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_Rect &rect)
+{
+ CFX_RectF rtText;
+ rtText.Set((FX_FLOAT)rect.left, (FX_FLOAT)rect.top, (FX_FLOAT)rect.width, (FX_FLOAT)rect.height);
+ DrawText(pwsStr, iLength, rtText);
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect)
+{
+ CFX_RectF rtText;
+ rtText.Set(rect.left, rect.top, rect.width, rect.height);
+ CFX_Matrix rm;
+ rm.SetReverse(m_Matrix);
+ rm.TransformRect(rtText);
+ DrawText(pwsStr, iLength, rtText, m_rtClip);
+}
+void CFDE_TextOut::DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y)
+{
+ CFX_RectF rtText;
+ rtText.Set(x, y, m_fFontSize * 1000.0f, m_fFontSize * 1000.0f);
+ DrawLogicText(pwsStr, iLength, rtText);
+}
+void CFDE_TextOut::DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect)
+{
+ CFX_RectF rtClip;
+ rtClip.Set(m_rtLogicClip.left, m_rtLogicClip.top, m_rtLogicClip.width, m_rtLogicClip.height);
+ m_Matrix.TransformRect(rtClip);
+ DrawText(pwsStr, iLength, rect, rtClip);
+}
+void CFDE_TextOut::DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect, const CFX_RectF &rtClip)
+{
+ FXSYS_assert(m_pFont != NULL && m_fFontSize >= 1.0f);
+ if (pwsStr == NULL || iLength < 1) {
+ return;
+ }
+ if (rect.width < m_fFontSize || rect.height < m_fFontSize) {
+ return;
+ }
+ FX_FLOAT fLineWidth = rect.width;
+ if (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) {
+ fLineWidth = rect.height;
+ }
+ m_pTxtBreak->SetLineWidth(fLineWidth);
+ m_ttoLines.RemoveAll(TRUE);
+ m_wsText.Empty();
+ LoadText(pwsStr, iLength, rect);
+ if (m_dwStyles & FDE_TTOSTYLE_Ellipsis) {
+ ReplaceWidthEllipsis();
+ }
+ Reload(rect);
+ DoAlignment(rect);
+ OnDraw(rtClip);
+}
+void CFDE_TextOut::ExpandBuffer(FX_INT32 iSize, FX_INT32 iType)
+{
+ switch (iType) {
+ case 0:
+ if (m_pCharWidths == NULL) {
+ m_pCharWidths = (FX_INT32*)FDE_Alloc(iSize * sizeof(FX_INT32));
+ m_iChars = iSize;
+ } else if (m_iChars < iSize) {
+ m_pCharWidths = (FX_INT32*)FDE_Realloc(m_pCharWidths, iSize * sizeof(FX_INT32));
+ m_iChars = iSize;
+ }
+ FXSYS_memset(m_pCharWidths, 0, iSize);
+ break;
+ case 1:
+ if (m_pEllCharWidths == NULL) {
+ m_pEllCharWidths = (FX_INT32*)FDE_Alloc(iSize * sizeof(FX_INT32));
+ m_iEllChars = iSize;
+ } else if (m_iEllChars < iSize) {
+ m_pEllCharWidths = (FX_INT32*)FDE_Realloc(m_pEllCharWidths, iSize * sizeof(FX_INT32));
+ m_iEllChars = iSize;
+ }
+ FXSYS_memset(m_pEllCharWidths, 0, iSize);
+ break;
+ case 2:
+ if (m_pCharPos == NULL) {
+ m_pCharPos = (FXTEXT_CHARPOS*)FDE_Alloc(iSize * sizeof(FXTEXT_CHARPOS));
+ m_iCharPosSize = iSize;
+ } else if (m_iCharPosSize < iSize) {
+ m_pCharPos = (FXTEXT_CHARPOS*)FDE_Realloc(m_pCharPos, iSize * sizeof(FXTEXT_CHARPOS));
+ m_iCharPosSize = iSize;
+ }
+ break;
+ }
+}
+void CFDE_TextOut::LoadEllipsis()
+{
+ if (!m_bElliChanged) {
+ return;
+ }
+ m_bElliChanged = FALSE;
+ m_iEllipsisWidth = 0;
+ FX_INT32 iLength = m_wsEllipsis.GetLength();
+ if (iLength < 1) {
+ return;
+ }
+ ExpandBuffer(iLength, 1);
+ FX_LPCWSTR pStr = (FX_LPCWSTR)m_wsEllipsis;
+ FX_INT32 *pCharWidths = m_pEllCharWidths;
+ FX_DWORD dwBreakStatus;
+ FX_WCHAR wch;
+ while (iLength-- > 0) {
+ wch = *pStr++;
+ dwBreakStatus = m_pTxtBreak->AppendChar(wch);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetrieveEllPieces(pCharWidths);
+ }
+ }
+ dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetrieveEllPieces(pCharWidths);
+ }
+ m_pTxtBreak->Reset();
+}
+void CFDE_TextOut::RetrieveEllPieces(FX_INT32 *&pCharWidths)
+{
+ FX_INT32 iCount = m_pTxtBreak->CountBreakPieces();
+ CFX_Char *pTC;
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ const CFX_TxtPiece *pPiece = m_pTxtBreak->GetBreakPiece(i);
+ FX_INT32 iPieceChars = pPiece->GetLength();
+ for (FX_INT32 j = 0; j < iPieceChars; j++) {
+ pTC = pPiece->GetCharPtr(j);
+ if (pTC->m_iCharWidth <= 0) {
+ *pCharWidths = 0;
+ } else {
+ *pCharWidths = pTC->m_iCharWidth;
+ }
+ m_iEllipsisWidth += *pCharWidths;
+ pCharWidths++;
+ }
+ }
+ m_pTxtBreak->ClearBreakPieces();
+}
+void CFDE_TextOut::LoadText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect)
+{
+ FX_LPWSTR pStr = m_wsText.GetBuffer(iLength);
+ FX_INT32 iTxtLength = iLength;
+ ExpandBuffer(iTxtLength, 0);
+ FX_BOOL bHotKey = (m_dwStyles & FDE_TTOSTYLE_HotKey) ? TRUE : FALSE;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_BOOL bLineWrap = (m_dwStyles & FDE_TTOSTYLE_LineWrap) ? TRUE : FALSE;
+ FX_FLOAT fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
+ FX_FLOAT fLineStop = bVertical ? rect.left : rect.bottom();
+ m_fLinePos = bVertical ? rect.right() : rect.top;
+ if (bVertical) {
+ fLineStep = -fLineStep;
+ }
+ m_hotKeys.RemoveAll();
+ FX_INT32 iStartChar = 0;
+ FX_INT32 iChars = 0;
+ FX_INT32 iPieceWidths = 0;
+ FX_DWORD dwBreakStatus;
+ FX_WCHAR wch;
+ FX_BOOL bRet = FALSE;
+ while (iTxtLength-- > 0) {
+ wch = *pwsStr++;
+ if (wch == L'&' && bHotKey && (pStr - 1) != NULL && *(pStr - 1) != L'&') {
+ if (iTxtLength > 0) {
+ m_hotKeys.Add(iChars);
+ }
+ continue;
+ }
+ *pStr++ = wch;
+ iChars++;
+ dwBreakStatus = m_pTxtBreak->AppendChar(wch);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ FX_BOOL bEndofLine = RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, FALSE, rect);
+ if (bEndofLine && (bLineWrap || (dwBreakStatus > FX_TXTBREAK_LineBreak && !bLineWrap))) {
+ iPieceWidths = 0;
+ m_iCurLine++;
+ m_fLinePos += fLineStep;
+ }
+ if ((bVertical && m_fLinePos + fLineStep < fLineStop) || (!bVertical && m_fLinePos + fLineStep > fLineStop)) {
+ FX_INT32 iCurLine = m_iCurLine;
+ if (bEndofLine) {
+ iCurLine--;
+ }
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(iCurLine);
+ pLine->m_bNewReload = TRUE;
+ bRet = TRUE;
+ break;
+ }
+ }
+ }
+ dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak && !bRet) {
+ RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, FALSE, rect);
+ }
+ m_pTxtBreak->ClearBreakPieces();
+ m_pTxtBreak->Reset();
+ m_wsText.ReleaseBuffer(iLength);
+}
+FX_BOOL CFDE_TextOut::RetriecePieces(FX_DWORD dwBreakStatus, FX_INT32 &iStartChar, FX_INT32 &iPieceWidths, FX_BOOL bReload,
+ const CFX_RectF &rect)
+{
+ FX_BOOL bSingleLine = (m_dwStyles & FDE_TTOSTYLE_SingleLine) ? TRUE : FALSE;
+ FX_BOOL bLineWrap = (m_dwStyles & FDE_TTOSTYLE_LineWrap) ? TRUE : FALSE;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_FLOAT fLineStep = (m_fLineSpace > m_fFontSize) ? m_fLineSpace : m_fFontSize;
+ if (bVertical) {
+ fLineStep = -fLineStep;
+ }
+ CFX_Char *pTC = NULL;
+ FX_BOOL bNeedReload = FALSE;
+ FX_FLOAT fLineWidth = bVertical ? rect.Height() : rect.Width();
+ FX_INT32 iLineWidth = FXSYS_round(fLineWidth * 20000.0f);
+ FX_INT32 iCount = m_pTxtBreak->CountBreakPieces();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ const CFX_TxtPiece *pPiece = m_pTxtBreak->GetBreakPiece(i);
+ FX_INT32 iPieceChars = pPiece->GetLength();
+ FX_INT32 iChar = iStartChar;
+ FX_INT32 iWidth = 0;
+ FX_INT32 j = 0;
+ for (; j < iPieceChars; j++) {
+ pTC = pPiece->GetCharPtr(j);
+ FX_INT32 iCurCharWidth = pTC->m_iCharWidth > 0 ? pTC->m_iCharWidth : 0;
+ if (bSingleLine || !bLineWrap) {
+ if (iLineWidth - iPieceWidths - iWidth < iCurCharWidth) {
+ bNeedReload = TRUE;
+ break;
+ }
+ }
+ iWidth += iCurCharWidth;
+ m_pCharWidths[iChar++] = iCurCharWidth;
+ }
+ if (j == 0 && !bReload) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(m_iCurLine);
+ pLine->m_bNewReload = TRUE;
+ } else if (j > 0) {
+ CFX_RectF rtPiece;
+ if (bVertical) {
+ rtPiece.left = m_fLinePos;
+ rtPiece.top = rect.top + (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
+ rtPiece.width = fLineStep;
+ rtPiece.height = iWidth / 20000.0f;
+ } else {
+ rtPiece.left = rect.left + (FX_FLOAT)pPiece->m_iStartPos / 20000.0f;
+ rtPiece.top = m_fLinePos;
+ rtPiece.width = iWidth / 20000.0f;
+ rtPiece.height = fLineStep;
+ }
+ FDE_TTOPIECE ttoPiece;
+ ttoPiece.iStartChar = iStartChar;
+ ttoPiece.iChars = j;
+ ttoPiece.rtPiece = rtPiece;
+ ttoPiece.dwCharStyles = pPiece->m_dwCharStyles;
+ if (FX_IsOdd(pPiece->m_iBidiLevel)) {
+ ttoPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel;
+ }
+ AppendPiece(ttoPiece, bNeedReload, (bReload && i == iCount - 1));
+ }
+ iStartChar += iPieceChars;
+ iPieceWidths += iWidth;
+ }
+ m_pTxtBreak->ClearBreakPieces();
+ FX_BOOL bRet = bSingleLine || bLineWrap || (!bLineWrap && bNeedReload) || dwBreakStatus == FX_TXTBREAK_ParagraphBreak;
+ return bRet;
+}
+void CFDE_TextOut::AppendPiece(const FDE_TTOPIECE &ttoPiece, FX_BOOL bNeedReload, FX_BOOL bEnd)
+{
+ if (m_iCurLine >= m_ttoLines.GetSize()) {
+ CFDE_TTOLine ttoLine;
+ ttoLine.m_bNewReload = bNeedReload;
+ m_iCurPiece = ttoLine.AddPiece(m_iCurPiece, ttoPiece);
+ m_iCurLine = m_ttoLines.Add(ttoLine);
+ } else {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(m_iCurLine);
+ pLine->m_bNewReload = bNeedReload;
+ m_iCurPiece = pLine->AddPiece(m_iCurPiece, ttoPiece);
+ if (bEnd) {
+ FX_INT32 iPieces = pLine->GetSize();
+ if (m_iCurPiece < iPieces) {
+ pLine->RemoveLast(iPieces - m_iCurPiece - 1);
+ }
+ }
+ }
+ if (!bEnd && bNeedReload) {
+ m_iCurPiece = 0;
+ }
+}
+void CFDE_TextOut::ReplaceWidthEllipsis()
+{
+ LoadEllipsis();
+ FX_INT32 iLength = m_wsEllipsis.GetLength();
+ if (iLength < 1) {
+ return;
+ }
+ FX_INT32 iLines = m_ttoLines.GetSize();
+ for (FX_INT32 i = 0; i < iLines; i++) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(i);
+ if (!pLine->m_bNewReload) {
+ continue;
+ }
+ FX_INT32 iEllipsisCharIndex = iLength - 1;
+ FX_INT32 iCharWidth = 0;
+ FX_INT32 iCharCount = 0;
+ FX_INT32 iPiece = pLine->GetSize();
+ while (iPiece-- > 0) {
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(iPiece);
+ if (pPiece == NULL) {
+ break;
+ }
+ for (FX_INT32 j = pPiece->iChars - 1; j >= 0; j--) {
+ if (iEllipsisCharIndex < 0) {
+ break;
+ }
+ FX_INT32 index = pPiece->iStartChar + j;
+ iCharWidth += m_pCharWidths[index];
+ iCharCount++;
+ if (iCharCount <= iLength) {
+ m_wsText.SetAt(index, m_wsEllipsis.GetAt(iEllipsisCharIndex));
+ m_pCharWidths[index] = m_pEllCharWidths[iEllipsisCharIndex];
+ } else if (iCharWidth <= m_iEllipsisWidth) {
+ m_wsText.SetAt(index, 0);
+ m_pCharWidths[index] = 0;
+ }
+ iEllipsisCharIndex--;
+ }
+ if (iEllipsisCharIndex < 0) {
+ break;
+ }
+ }
+ }
+}
+void CFDE_TextOut::Reload(const CFX_RectF &rect)
+{
+ FX_INT32 iCount = m_ttoLines.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i++) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(i);
+ if (pLine == NULL || !pLine->m_bNewReload) {
+ continue;
+ }
+ m_iCurLine = i;
+ m_iCurPiece = 0;
+ ReloadLinePiece(pLine, rect);
+ }
+}
+void CFDE_TextOut::ReloadLinePiece(CFDE_TTOLine *pLine, const CFX_RectF &rect)
+{
+ FX_LPCWSTR pwsStr = (FX_LPCWSTR)m_wsText;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_INT32 iPieceWidths = 0;
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(0);
+ FX_INT32 iStartChar = pPiece->iStartChar;
+ m_fLinePos = bVertical ? pPiece->rtPiece.left : pPiece->rtPiece.top;
+ FX_INT32 iPieceCount = pLine->GetSize();
+ FX_INT32 iPieceIndex = 0;
+ FX_DWORD dwBreakStatus = 0;
+ FX_WCHAR wch;
+ while (iPieceIndex < iPieceCount) {
+ FX_INT32 iStar = iStartChar;
+ FX_INT32 iEnd = pPiece->iChars + iStar;
+ while (iStar < iEnd) {
+ wch = *(pwsStr + iStar);
+ dwBreakStatus = m_pTxtBreak->AppendChar(wch);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, TRUE, rect);
+ }
+ iStar++;
+ }
+ iPieceIndex++;
+ pPiece = pLine->GetPtrAt(iPieceIndex);
+ }
+ dwBreakStatus = m_pTxtBreak->EndBreak(FX_TXTBREAK_ParagraphBreak);
+ if (dwBreakStatus > FX_TXTBREAK_PieceBreak) {
+ RetriecePieces(dwBreakStatus, iStartChar, iPieceWidths, TRUE, rect);
+ }
+ m_pTxtBreak->Reset();
+}
+void CFDE_TextOut::DoAlignment(const CFX_RectF &rect)
+{
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ FX_FLOAT fLineStopS = bVertical ? rect.right() : rect.bottom();
+ FX_INT32 iLines = m_ttoLines.GetSize();
+ if (iLines < 1) {
+ return;
+ }
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(iLines - 1);
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(0);
+ if (pPiece == NULL) {
+ return;
+ }
+ FX_FLOAT fLineStopD = bVertical ? pPiece->rtPiece.right() : pPiece->rtPiece.bottom();
+ FX_FLOAT fInc = fLineStopS - fLineStopD;
+ if (m_iAlignment >= FDE_TTOALIGNMENT_CenterLeft && m_iAlignment < FDE_TTOALIGNMENT_BottomLeft) {
+ fInc /= 2.0f;
+ } else if (m_iAlignment < FDE_TTOALIGNMENT_CenterLeft) {
+ fInc = 0.0f;
+ }
+ if (fInc < 1.0f) {
+ return;
+ }
+ for (FX_INT32 i = 0; i < iLines; i++) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(i);
+ FX_INT32 iPieces = pLine->GetSize();
+ for (FX_INT32 j = 0; j < iPieces; j++) {
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(j);
+ if (bVertical) {
+ pPiece->rtPiece.left += fInc;
+ } else {
+ pPiece->rtPiece.top += fInc;
+ }
+ }
+ }
+}
+void CFDE_TextOut::OnDraw(const CFX_RectF &rtClip)
+{
+ if (m_pRenderDevice == NULL) {
+ return;
+ }
+ FX_INT32 iLines = m_ttoLines.GetSize();
+ if (iLines < 1) {
+ return;
+ }
+ IFDE_SolidBrush *pBrush = (IFDE_SolidBrush*)IFDE_Brush::Create(FDE_BRUSHTYPE_Solid);
+ pBrush->SetColor(m_TxtColor);
+ IFDE_Pen *pPen = NULL;
+ FDE_HDEVICESTATE hDev = m_pRenderDevice->SaveState();
+ if (rtClip.Width() > 0.0f && rtClip.Height() > 0.0f) {
+ m_pRenderDevice->SetClipRect(rtClip);
+ }
+ for (FX_INT32 i = 0; i < iLines; i++) {
+ CFDE_TTOLine *pLine = m_ttoLines.GetPtrAt(i);
+ FX_INT32 iPieces = pLine->GetSize();
+ for (FX_INT32 j = 0; j < iPieces; j++) {
+ FDE_LPTTOPIECE pPiece = pLine->GetPtrAt(j);
+ if (pPiece == NULL) {
+ continue;
+ }
+ FX_INT32 iCount = GetDisplayPos(pPiece);
+ if (iCount > 0) {
+ m_pRenderDevice->DrawString(pBrush, m_pFont, m_pCharPos, iCount, m_fFontSize, &m_Matrix);
+ }
+ DrawLine(pPiece, pPen);
+ }
+ }
+ m_pRenderDevice->RestoreState(hDev);
+ if (pBrush) {
+ pBrush->Release();
+ }
+ if (pPen) {
+ pPen->Release();
+ }
+}
+FX_INT32 CFDE_TextOut::GetDisplayPos(FDE_LPTTOPIECE pPiece)
+{
+ FX_TXTRUN tr;
+ ToTextRun(pPiece, tr);
+ ExpandBuffer(tr.iLength, 2);
+ return m_pTxtBreak->GetDisplayPos(&tr, m_pCharPos);
+}
+FX_INT32 CFDE_TextOut::GetCharRects(FDE_LPTTOPIECE pPiece)
+{
+ FX_TXTRUN tr;
+ ToTextRun(pPiece, tr);
+ m_rectArray.RemoveAll();
+ return m_pTxtBreak->GetCharRects(&tr, m_rectArray);
+}
+void CFDE_TextOut::ToTextRun(const FDE_LPTTOPIECE pPiece, FX_TXTRUN &tr)
+{
+ tr.pAccess = NULL;
+ tr.pIdentity = NULL;
+ tr.pStr = (FX_LPCWSTR)m_wsText + pPiece->iStartChar;
+ tr.pWidths = m_pCharWidths + pPiece->iStartChar;
+ tr.iLength = pPiece->iChars;
+ tr.pFont = m_pFont;
+ tr.fFontSize = m_fFontSize;
+ tr.dwStyles = m_dwTxtBkStyles;
+ tr.iCharRotation = 0;
+ tr.dwCharStyles = pPiece->dwCharStyles;
+ tr.wLineBreakChar = m_wParagraphBkChar;
+ tr.pRect = &pPiece->rtPiece;
+}
+void CFDE_TextOut::DrawLine(const FDE_LPTTOPIECE pPiece, IFDE_Pen *&pPen)
+{
+ FX_BOOL bUnderLine = (m_dwStyles & FDE_TTOSTYLE_Underline) ? TRUE : FALSE;
+ FX_BOOL bStrikeOut = (m_dwStyles & FDE_TTOSTYLE_Strikeout) ? TRUE : FALSE;
+ FX_BOOL bHotKey = (m_dwStyles & FDE_TTOSTYLE_HotKey) ? TRUE : FALSE;
+ FX_BOOL bVertical = (m_dwStyles & FDE_TTOSTYLE_VerticalLayout) ? TRUE : FALSE;
+ if (!bUnderLine && !bStrikeOut && !bHotKey) {
+ return;
+ }
+ if (pPen == NULL) {
+ pPen = IFDE_Pen::Create();
+ pPen->SetColor(m_TxtColor);
+ }
+ IFDE_Path *pPath = IFDE_Path::Create();
+ FX_INT32 iLineCount = 0;
+ CFX_RectF rtText = pPiece->rtPiece;
+ CFX_PointF pt1, pt2;
+ if (bUnderLine) {
+ if (bVertical) {
+ pt1.x = rtText.left;
+ pt1.y = rtText.top;
+ pt2.x = rtText.left;
+ pt2.y = rtText.bottom();
+ } else {
+ pt1.x = rtText.left;
+ pt1.y = rtText.bottom();
+ pt2.x = rtText.right();
+ pt2.y = rtText.bottom();
+ }
+ pPath->AddLine(pt1, pt2);
+ iLineCount++;
+ }
+ if (bStrikeOut) {
+ if (bVertical) {
+ pt1.x = rtText.left + rtText.width * 2.0f / 5.0f;
+ pt1.y = rtText.top;;
+ pt2.x = pt1.x;
+ pt2.y = rtText.bottom();
+ } else {
+ pt1.x = rtText.left;
+ pt1.y = rtText.bottom() - rtText.height * 2.0f / 5.0f;
+ pt2.x = rtText.right();
+ pt2.y = pt1.y;
+ }
+ pPath->AddLine(pt1, pt2);
+ iLineCount++;
+ }
+ if (bHotKey) {
+ FX_INT32 iHotKeys = m_hotKeys.GetSize();
+ FX_INT32 iCount = GetCharRects(pPiece);
+ if (iCount > 0) {
+ for (FX_INT32 i = 0; i < iHotKeys; i++) {
+ FX_INT32 iCharIndex = m_hotKeys.GetAt(i);
+ if (iCharIndex >= pPiece->iStartChar && iCharIndex < pPiece->iStartChar + pPiece->iChars) {
+ CFX_RectF rect = m_rectArray.GetAt(iCharIndex - pPiece->iStartChar);
+ if (bVertical) {
+ pt1.x = rect.left;
+ pt1.y = rect.top;
+ pt2.x = rect.left;
+ pt2.y = rect.bottom();
+ } else {
+ pt1.x = rect.left;
+ pt1.y = rect.bottom();
+ pt2.x = rect.right();
+ pt2.y = rect.bottom();
+ }
+ pPath->AddLine(pt1, pt2);
+ iLineCount++;
+ }
+ }
+ }
+ }
+ if (iLineCount > 0) {
+ m_pRenderDevice->DrawPath(pPen, 1, pPath, &m_Matrix);
+ }
+ pPath->Release();
+}
+CFDE_TTOLine::CFDE_TTOLine()
+ : m_bNewReload(FALSE)
+ , m_pieces(5)
+ , m_iPieceCount(0)
+{
+}
+CFDE_TTOLine::CFDE_TTOLine(const CFDE_TTOLine &ttoLine)
+ : m_pieces(5)
+{
+ m_bNewReload = ttoLine.m_bNewReload;
+ m_iPieceCount = ttoLine.m_iPieceCount;
+ m_pieces.Copy(ttoLine.m_pieces);
+}
+CFDE_TTOLine::~CFDE_TTOLine()
+{
+}
+FX_INT32 CFDE_TTOLine::AddPiece(FX_INT32 index, const FDE_TTOPIECE &ttoPiece)
+{
+ if (index >= m_iPieceCount) {
+ index = m_pieces.Add(ttoPiece) + 1;
+ m_iPieceCount++;
+ } else {
+ FDE_TTOPIECE &piece = m_pieces.GetAt(index);
+ piece = ttoPiece;
+ }
+ return index;
+}
+FX_INT32 CFDE_TTOLine::GetSize() const
+{
+ return m_iPieceCount;
+}
+FDE_LPTTOPIECE CFDE_TTOLine::GetPtrAt(FX_INT32 index)
+{
+ if (index >= m_iPieceCount) {
+ return NULL;
+ }
+ return m_pieces.GetPtrAt(index);
+}
+void CFDE_TTOLine::RemoveLast(FX_INT32 iCount)
+{
+ m_pieces.RemoveLast(iCount);
+}
+void CFDE_TTOLine::RemoveAll(FX_BOOL bLeaveMemory)
+{
+ m_pieces.RemoveAll(bLeaveMemory);
+}
diff --git a/xfa/src/fdp/src/tto/fde_textout.h b/xfa/src/fdp/src/tto/fde_textout.h
new file mode 100644
index 0000000000..116ad89d5d
--- /dev/null
+++ b/xfa/src/fdp/src/tto/fde_textout.h
@@ -0,0 +1,132 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_TEXTOUT_IMP
+#define _FDE_TEXTOUT_IMP
+struct FDE_TTOPIECE {
+public:
+ FX_INT32 iStartChar;
+ FX_INT32 iChars;
+ FX_DWORD dwCharStyles;
+ CFX_RectF rtPiece;
+};
+typedef FDE_TTOPIECE * FDE_LPTTOPIECE;
+typedef CFX_MassArrayTemplate<FDE_TTOPIECE> CFDE_TTOPieceArray;
+class CFDE_TTOLine : public CFX_Target
+{
+public:
+ CFDE_TTOLine();
+ CFDE_TTOLine(const CFDE_TTOLine &ttoLine);
+ ~CFDE_TTOLine();
+ FX_INT32 AddPiece(FX_INT32 index, const FDE_TTOPIECE &ttoPiece);
+ FX_INT32 GetSize() const;
+ FDE_LPTTOPIECE GetPtrAt(FX_INT32 index);
+ void RemoveLast(FX_INT32 iCount);
+ void RemoveAll(FX_BOOL bLeaveMemory);
+ FX_BOOL m_bNewReload;
+ CFDE_TTOPieceArray m_pieces;
+protected:
+ FX_INT32 m_iPieceCount;
+};
+typedef CFX_ObjectMassArrayTemplate<CFDE_TTOLine> CFDE_TTOLineArray;
+class CFDE_TextOut : public IFDE_TextOut, public CFX_Target
+{
+public:
+ CFDE_TextOut();
+ ~CFDE_TextOut();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual void SetFont(IFX_Font *pFont);
+ virtual void SetFontSize(FX_FLOAT fFontSize);
+ virtual void SetTextColor(FX_ARGB color);
+ virtual void SetStyles(FX_DWORD dwStyles);
+ virtual void SetTabWidth(FX_FLOAT fTabWidth);
+ virtual void SetEllipsisString(const CFX_WideString &wsEllipsis);
+ virtual void SetParagraphBreakChar(FX_WCHAR wch);
+ virtual void SetAlignment(FX_INT32 iAlignment);
+ virtual void SetLineSpace(FX_FLOAT fLineSpace);
+ virtual void SetDIBitmap(CFX_DIBitmap *pDIB);
+ virtual void SetRenderDevice(CFX_RenderDevice *pDevice);
+ virtual void SetClipRect(const CFX_Rect &rtClip);
+ virtual void SetClipRect(const CFX_RectF &rtClip);
+ virtual void SetMatrix(const CFX_Matrix &matrix);
+ virtual void SetLineBreakTolerance(FX_FLOAT fTolerance);
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Size &size);
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size);
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_Rect &rect);
+ virtual void CalcSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect);
+
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_INT32 x, FX_INT32 y);
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y);
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_Rect &rect);
+ virtual void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect);
+
+ virtual void SetLogicClipRect(const CFX_RectF &rtClip);
+ virtual void CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_SizeF &size);
+ virtual void CalcLogicSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect);
+ virtual void DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, FX_FLOAT x, FX_FLOAT y);
+ virtual void DrawLogicText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect);
+ virtual FX_INT32 GetTotalLines();
+protected:
+ void CalcTextSize(FX_LPCWSTR pwsStr, FX_INT32 iLength, CFX_RectF &rect);
+ FX_BOOL RetrieveLineWidth(FX_DWORD dwBreakStatus, FX_FLOAT &fStartPos, FX_FLOAT &fWidth, FX_FLOAT &fHeight);
+ void SetLineWidth(CFX_RectF &rect);
+ void DrawText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect, const CFX_RectF &rtClip);
+ void LoadText(FX_LPCWSTR pwsStr, FX_INT32 iLength, const CFX_RectF &rect);
+ void LoadEllipsis();
+ void ExpandBuffer(FX_INT32 iSize, FX_INT32 iType);
+ void RetrieveEllPieces(FX_INT32 *&pCharWidths);
+
+ void Reload(const CFX_RectF &rect);
+ void ReloadLinePiece(CFDE_TTOLine *pLine, const CFX_RectF &rect);
+ FX_BOOL RetriecePieces(FX_DWORD dwBreakStatus, FX_INT32 &iStartChar, FX_INT32 &iPieceWidths, FX_BOOL bReload, const CFX_RectF &rect);
+ void AppendPiece(const FDE_TTOPIECE &ttoPiece, FX_BOOL bNeedReload, FX_BOOL bEnd);
+ void ReplaceWidthEllipsis();
+ void DoAlignment(const CFX_RectF &rect);
+ void OnDraw(const CFX_RectF &rtClip);
+ FX_INT32 GetDisplayPos(FDE_LPTTOPIECE pPiece);
+ FX_INT32 GetCharRects(FDE_LPTTOPIECE pPiece);
+
+ void ToTextRun(const FDE_LPTTOPIECE pPiece, FX_TXTRUN &tr);
+ void DrawLine(const FDE_LPTTOPIECE pPiece, IFDE_Pen *&pPen);
+
+ IFX_TxtBreak *m_pTxtBreak;
+ IFX_Font *m_pFont;
+ FX_FLOAT m_fFontSize;
+ FX_FLOAT m_fLineSpace;
+ FX_FLOAT m_fLinePos;
+ FX_FLOAT m_fTolerance;
+
+ FX_INT32 m_iAlignment;
+ FX_INT32 m_iTxtBkAlignment;
+ FX_INT32 *m_pCharWidths;
+ FX_INT32 m_iChars;
+ FX_INT32 *m_pEllCharWidths;
+ FX_INT32 m_iEllChars;
+ FX_WCHAR m_wParagraphBkChar;
+ FX_ARGB m_TxtColor;
+ FX_DWORD m_dwStyles;
+ FX_DWORD m_dwTxtBkStyles;
+ CFX_WideString m_wsEllipsis;
+ FX_BOOL m_bElliChanged;
+ FX_INT32 m_iEllipsisWidth;
+ CFX_WideString m_wsText;
+ CFX_RectF m_rtClip;
+ CFX_RectF m_rtLogicClip;
+ CFX_Matrix m_Matrix;
+ CFDE_TTOLineArray m_ttoLines;
+ FX_INT32 m_iCurLine;
+ FX_INT32 m_iCurPiece;
+ FX_INT32 m_iTotalLines;
+ FXTEXT_CHARPOS *m_pCharPos;
+ FX_INT32 m_iCharPosSize;
+ IFDE_RenderDevice *m_pRenderDevice;
+ CFX_Int32Array m_hotKeys;
+ CFX_RectFArray m_rectArray;
+};
+#endif
diff --git a/xfa/src/fdp/src/xml/fde_xml.cpp b/xfa/src/fdp/src/xml/fde_xml.cpp
new file mode 100644
index 0000000000..3ee4b4028c
--- /dev/null
+++ b/xfa/src/fdp/src/xml/fde_xml.cpp
@@ -0,0 +1,2712 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "../../../foxitlib.h"
+#include "fde_xml.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define FDE_XMLVALIDCHARRANGENUM 5
+static FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = {{0x09, 0x09}, {0x0A, 0x0A}, {0x0D, 0x0D}, {0x20, 0xD7FF}, {0xE000, 0xFFFD}};
+FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch)
+{
+ FX_INT32 iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid;
+ while (iStart <= iEnd) {
+ iMid = (iStart + iEnd) / 2;
+ if (ch < g_XMLValidCharRange[iMid][0]) {
+ iEnd = iMid - 1;
+ } else if (ch > g_XMLValidCharRange[iMid][1]) {
+ iStart = iMid + 1;
+ } else {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch)
+{
+ return ch == L' ' || ch == 0x0A || ch == 0x0D || ch == 0x09;
+}
+typedef struct _FDE_XMLNAMECHAR {
+ FX_WCHAR wStart;
+ FX_WCHAR wEnd;
+ FX_BOOL bStartChar;
+} FDE_XMLNAMECHAR;
+#define FDE_XMLNAMECHARSNUM 20
+static FDE_XMLNAMECHAR g_XMLNameChars[FDE_XMLNAMECHARSNUM] = {
+ {L'-', L'.', FALSE}, {L'0', L'9', FALSE}, {L':', L':', FALSE}, {L'A', L'Z', TRUE},
+ {L'_', L'_', TRUE}, {L'a', L'z', TRUE}, {0xB7, 0xB7, FALSE}, {0xC0, 0xD6, TRUE},
+ {0xD8, 0xF6, TRUE}, {0xF8, 0x02FF, TRUE}, {0x0300, 0x036F, FALSE}, {0x0370, 0x037D, TRUE},
+ {0x037F, 0x1FFF, TRUE}, {0x200C, 0x200D, TRUE}, {0x203F, 0x2040, FALSE}, {0x2070, 0x218F, TRUE},
+ {0x2C00, 0x2FEF, TRUE}, {0x3001, 0xD7FF, TRUE}, {0xF900, 0xFDCF, TRUE}, {0xFDF0, 0xFFFD, TRUE},
+};
+FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar)
+{
+ FX_INT32 iStart = 0, iEnd = FDE_XMLNAMECHARSNUM - 1, iMid;
+ while (iStart <= iEnd) {
+ iMid = (iStart + iEnd) / 2;
+ if (ch < g_XMLNameChars[iMid].wStart) {
+ iEnd = iMid - 1;
+ } else if (ch > g_XMLNameChars[iMid].wEnd) {
+ iStart = iMid + 1;
+ } else {
+ if (bFirstChar) {
+ return g_XMLNameChars[iMid].bStartChar;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+#ifdef __cplusplus
+}
+#endif
+CFDE_XMLNode::CFDE_XMLNode()
+ : m_pParent(NULL)
+ , m_pChild(NULL)
+ , m_pPrior(NULL)
+ , m_pNext(NULL)
+{
+}
+CFDE_XMLNode::~CFDE_XMLNode()
+{
+ DeleteChildren();
+}
+void CFDE_XMLNode::DeleteChildren()
+{
+ CFDE_XMLNode *pChild = m_pChild, *pTemp;
+ while (pChild != NULL) {
+ pTemp = pChild->m_pNext;
+ pChild->Release();
+ pChild = pTemp;
+ }
+ m_pChild = NULL;
+}
+FX_INT32 CFDE_XMLNode::CountChildNodes() const
+{
+ FX_INT32 iCount = 0;
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ iCount ++;
+ pChild = pChild->m_pNext;
+ }
+ return iCount;
+}
+CFDE_XMLNode* CFDE_XMLNode::GetChildNode(FX_INT32 index) const
+{
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ if (index == 0) {
+ return pChild;
+ }
+ index --;
+ pChild = pChild->m_pNext;
+ }
+ return NULL;
+}
+FX_INT32 CFDE_XMLNode::GetChildNodeIndex(CFDE_XMLNode *pNode) const
+{
+ FX_INT32 index = 0;
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ if (pChild == pNode) {
+ return index;
+ }
+ index ++;
+ pChild = pChild->m_pNext;
+ }
+ return -1;
+}
+CFDE_XMLNode* CFDE_XMLNode::GetPath(FX_LPCWSTR pPath, FX_INT32 iLength, FX_BOOL bQualifiedName) const
+{
+ FXSYS_assert(pPath != NULL);
+ if (iLength < 0) {
+ iLength = FXSYS_wcslen(pPath);
+ }
+ if (iLength == 0) {
+ return NULL;
+ }
+ CFX_WideString csPath;
+ FX_LPCWSTR pStart = pPath, pEnd = pPath + iLength;
+ FX_WCHAR ch;
+ while (pStart < pEnd) {
+ ch = *pStart ++;
+ if (ch == L'/') {
+ break;
+ } else {
+ csPath += ch;
+ }
+ }
+ iLength -= pStart - pPath;
+ CFDE_XMLNode *pFind = NULL;
+ if (csPath.GetLength() < 1) {
+ pFind = GetNodeItem(IFDE_XMLNode::Root);
+ } else if (csPath.Compare(L"..") == 0) {
+ pFind = m_pParent;
+ } else if (csPath.Compare(L".") == 0) {
+ pFind = (CFDE_XMLNode*)this;
+ } else {
+ CFX_WideString wsTag;
+ CFDE_XMLNode *pNode = m_pChild;
+ while (pNode != NULL) {
+ if (pNode->GetType() == FDE_XMLNODE_Element) {
+ if (bQualifiedName) {
+ ((CFDE_XMLElement*)pNode)->GetTagName(wsTag);
+ } else {
+ ((CFDE_XMLElement*)pNode)->GetLocalTagName(wsTag);
+ }
+ if (wsTag.Compare(csPath) == 0) {
+ if (iLength < 1) {
+ pFind = pNode;
+ } else {
+ pFind = pNode->GetPath(pStart, iLength, bQualifiedName);
+ }
+ if (pFind != NULL) {
+ return pFind;
+ }
+ }
+ }
+ pNode = pNode->m_pNext;
+ }
+ }
+ if (pFind == NULL || iLength < 1) {
+ return pFind;
+ }
+ return pFind->GetPath(pStart, iLength, bQualifiedName);
+}
+FX_INT32 CFDE_XMLNode::InsertChildNode(CFDE_XMLNode *pNode, FX_INT32 index)
+{
+ FXSYS_assert(pNode != NULL);
+ pNode->m_pParent = this;
+ if (m_pChild == NULL) {
+ m_pChild = pNode;
+ pNode->m_pPrior = NULL;
+ pNode->m_pNext = NULL;
+ return 0;
+ } else if (index == 0) {
+ pNode->m_pNext = m_pChild;
+ pNode->m_pPrior = NULL;
+ m_pChild->m_pPrior = pNode;
+ m_pChild = pNode;
+ return 0;
+ }
+ FX_INT32 iCount = 0;
+ CFDE_XMLNode *pFind = m_pChild;
+ while (++iCount != index && pFind->m_pNext != NULL) {
+ pFind = pFind->m_pNext;
+ }
+ pNode->m_pPrior = pFind;
+ pNode->m_pNext = pFind->m_pNext;
+ if (pFind->m_pNext != NULL) {
+ pFind->m_pNext->m_pPrior = pNode;
+ }
+ pFind->m_pNext = pNode;
+ return iCount;
+}
+void CFDE_XMLNode::RemoveChildNode(CFDE_XMLNode *pNode)
+{
+ FXSYS_assert(m_pChild != NULL && pNode != NULL);
+ if (m_pChild == pNode) {
+ m_pChild = pNode->m_pNext;
+ } else {
+ pNode->m_pPrior->m_pNext = pNode->m_pNext;
+ }
+ if (pNode->m_pNext != NULL) {
+ pNode->m_pNext->m_pPrior = pNode->m_pPrior;
+ }
+ pNode->m_pParent = NULL;
+ pNode->m_pNext = NULL;
+ pNode->m_pPrior = NULL;
+}
+CFDE_XMLNode* CFDE_XMLNode::GetNodeItem(IFDE_XMLNode::NodeItem eItem) const
+{
+ switch (eItem) {
+ case IFDE_XMLNode::Root: {
+ CFDE_XMLNode *pParent = (CFDE_XMLNode*)this;
+ while (pParent->m_pParent != NULL) {
+ pParent = pParent->m_pParent;
+ }
+ return pParent;
+ }
+ case IFDE_XMLNode::Parent:
+ return m_pParent;
+ case IFDE_XMLNode::FirstSibling: {
+ CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
+ while (pItem->m_pPrior != NULL) {
+ pItem = pItem->m_pPrior;
+ }
+ return pItem == (CFDE_XMLNode*)this ? NULL : pItem;
+ }
+ case IFDE_XMLNode::PriorSibling:
+ return m_pPrior;
+ case IFDE_XMLNode::NextSibling:
+ return m_pNext;
+ case IFDE_XMLNode::LastSibling: {
+ CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
+ while (pItem->m_pNext != NULL) {
+ pItem = pItem->m_pNext;
+ }
+ return pItem == (CFDE_XMLNode*)this ? NULL : pItem;
+ }
+ case IFDE_XMLNode::FirstNeighbor: {
+ CFDE_XMLNode *pParent = (CFDE_XMLNode*)this;
+ while (pParent->m_pParent != NULL) {
+ pParent = pParent->m_pParent;
+ }
+ return pParent == (CFDE_XMLNode*)this ? NULL : pParent;
+ }
+ case IFDE_XMLNode::PriorNeighbor: {
+ if (m_pPrior == NULL) {
+ return m_pParent;
+ }
+ CFDE_XMLNode *pItem = m_pPrior;
+ while (CFDE_XMLNode *pTemp = pItem->m_pChild) {
+ pItem = pTemp;
+ while ((pTemp = pItem->m_pNext) != NULL) {
+ pItem = pTemp;
+ }
+ }
+ return pItem;
+ }
+ case IFDE_XMLNode::NextNeighbor: {
+ if (m_pChild != NULL) {
+ return m_pChild;
+ }
+ if (m_pNext != NULL) {
+ return m_pNext;
+ }
+ CFDE_XMLNode *pItem = m_pParent;
+ while (pItem != NULL) {
+ if (pItem->m_pNext != NULL) {
+ return pItem->m_pNext;
+ }
+ pItem = pItem->m_pParent;
+ }
+ return NULL;
+ }
+ case IFDE_XMLNode::LastNeighbor: {
+ CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
+ while (pItem->m_pParent != NULL) {
+ pItem = pItem->m_pParent;
+ }
+ while (TRUE) {
+ while (pItem->m_pNext != NULL) {
+ pItem = pItem->m_pNext;
+ }
+ if (pItem->m_pChild == NULL) {
+ break;
+ }
+ pItem = pItem->m_pChild;
+ }
+ return pItem == (CFDE_XMLNode*)this ? NULL : pItem;
+ }
+ case IFDE_XMLNode::FirstChild:
+ return m_pChild;
+ case IFDE_XMLNode::LastChild: {
+ if (m_pChild == NULL) {
+ return NULL;
+ }
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild->m_pNext != NULL) {
+ pChild = pChild->m_pNext;
+ }
+ return pChild;
+ }
+ default:
+ break;
+ }
+ return NULL;
+}
+FX_INT32 CFDE_XMLNode::GetNodeLevel() const
+{
+ FX_INT32 iLevel = 0;
+ CFDE_XMLNode *pItem = (CFDE_XMLNode*)this;
+ while ((pItem = pItem->m_pParent) != NULL) {
+ iLevel ++;
+ }
+ return iLevel;
+}
+FX_BOOL CFDE_XMLNode::InsertNodeItem(IFDE_XMLNode::NodeItem eItem, CFDE_XMLNode *pNode)
+{
+ FXSYS_assert(pNode != NULL);
+ switch (eItem) {
+ case IFDE_XMLNode::NextSibling: {
+ pNode->m_pParent = m_pParent;
+ pNode->m_pNext = m_pNext;
+ pNode->m_pPrior = this;
+ if (m_pNext) {
+ m_pNext->m_pPrior = pNode;
+ }
+ m_pNext = pNode;
+ return TRUE;
+ }
+ case IFDE_XMLNode::PriorSibling: {
+ pNode->m_pParent = m_pParent;
+ pNode->m_pNext = this;
+ pNode->m_pPrior = m_pPrior;
+ if (m_pPrior) {
+ m_pPrior->m_pNext = pNode;
+ } else if (m_pParent) {
+ m_pParent->m_pChild = pNode;
+ }
+ m_pPrior = pNode;
+ return TRUE;
+ }
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+CFDE_XMLNode* CFDE_XMLNode::RemoveNodeItem(IFDE_XMLNode::NodeItem eItem)
+{
+ CFDE_XMLNode* pNode = NULL;
+ switch (eItem) {
+ case IFDE_XMLNode::NextSibling:
+ if (m_pNext) {
+ pNode = m_pNext;
+ m_pNext = pNode->m_pNext;
+ if (m_pNext) {
+ m_pNext->m_pPrior = this;
+ }
+ pNode->m_pParent = NULL;
+ pNode->m_pNext = NULL;
+ pNode->m_pPrior = NULL;
+ }
+ break;
+ default:
+ break;
+ }
+ return pNode;
+}
+CFDE_XMLNode* CFDE_XMLNode::Clone(FX_BOOL bRecursive)
+{
+ return NULL;
+}
+void CFDE_XMLNode::SaveXMLNode(IFX_Stream *pXMLStream)
+{
+ CFDE_XMLNode *pNode = (CFDE_XMLNode*)this;
+ FXSYS_assert(pXMLStream != NULL && pNode != NULL);
+ switch (pNode->GetType()) {
+ case FDE_XMLNODE_Instruction: {
+ CFX_WideString ws;
+ CFDE_XMLInstruction *pInstruction = (CFDE_XMLInstruction*)pNode;
+ if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) {
+ ws = L"<?xml version=\"1.0\" encoding=\"";
+ FX_WORD wCodePage = pXMLStream->GetCodePage();
+ if (wCodePage == FX_CODEPAGE_UTF16LE) {
+ ws += L"UTF-16";
+ } else if (wCodePage == FX_CODEPAGE_UTF16BE) {
+ ws += L"UTF-16be";
+ } else {
+ ws += L"UTF-8";
+ }
+ ws += L"\"?>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ } else {
+ ws.Format((FX_LPCWSTR)L"<?%s", (FX_LPCWSTR)pInstruction->m_wsTarget);
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFX_WideStringArray &attributes = pInstruction->m_Attributes;
+ FX_INT32 i, iCount = attributes.GetSize();
+ CFX_WideString wsValue;
+ for (i = 0; i < iCount; i += 2) {
+ ws = L" ";
+ ws += attributes[i];
+ ws += L"=\"";
+ wsValue = attributes[i + 1];
+ wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ ws += wsValue;
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ CFX_WideStringArray &targetdata = pInstruction->m_TargetData;
+ iCount = targetdata.GetSize();
+ for (i = 0; i < iCount; i++) {
+ ws = L" \"";
+ ws += targetdata[i];
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ ws = L"?>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ }
+ break;
+ case FDE_XMLNODE_Element: {
+ CFX_WideString ws;
+ ws = L"<";
+ ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFX_WideStringArray &attributes = ((CFDE_XMLElement*)pNode)->m_Attributes;
+ FX_INT32 iCount = attributes.GetSize();
+ CFX_WideString wsValue;
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ ws = L" ";
+ ws += attributes[i];
+ ws += L"=\"";
+ wsValue = attributes[i + 1];
+ wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ ws += wsValue;
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ if (pNode->m_pChild == NULL) {
+ ws = L"\n/>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ } else {
+ ws = L"\n>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFDE_XMLNode *pChild = pNode->m_pChild;
+ while (pChild != NULL) {
+ pChild->SaveXMLNode(pXMLStream);
+ pChild = pChild->m_pNext;
+ }
+ ws = L"</";
+ ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
+ ws += L"\n>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ }
+ break;
+ case FDE_XMLNODE_Text: {
+ CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText;
+ ws.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ ws.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ ws.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ ws.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ ws.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ break;
+ case FDE_XMLNODE_CharData: {
+ CFX_WideString ws = L"<![CDATA[";
+ ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData;
+ ws += L"]]>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ break;
+ case FDE_XMLNODE_Unknown:
+ break;
+ default:
+ break;
+ }
+}
+void CFDE_XMLNode::CloneChildren(CFDE_XMLNode* pClone)
+{
+ if (!m_pChild) {
+ return;
+ }
+ CFDE_XMLNode* pNext = m_pChild;
+ CFDE_XMLNode* pCloneNext = pNext->Clone(TRUE);
+ pClone->InsertChildNode(pCloneNext);
+ pNext = pNext->m_pNext;
+ while (pNext) {
+ CFDE_XMLNode* pChild = pNext->Clone(TRUE);
+ pCloneNext->InsertNodeItem(IFDE_XMLNode::NextSibling, pChild);
+ pCloneNext = pChild;
+ pNext = pNext->m_pNext;
+ }
+}
+IFDE_XMLInstruction* IFDE_XMLInstruction::Create(const CFX_WideString &wsTarget)
+{
+ return (IFDE_XMLInstruction*)FDE_New CFDE_XMLInstruction(wsTarget);
+}
+CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString &wsTarget)
+ : CFDE_XMLNode()
+ , m_wsTarget(wsTarget)
+ , m_TargetData()
+ , m_Attributes()
+{
+ FXSYS_assert(m_wsTarget.GetLength() > 0);
+}
+CFDE_XMLNode* CFDE_XMLInstruction::Clone(FX_BOOL bRecursive)
+{
+ CFDE_XMLInstruction* pClone = FDE_New CFDE_XMLInstruction(m_wsTarget);
+ if (!pClone) {
+ return pClone;
+ }
+ pClone->m_Attributes.Copy(m_Attributes);
+ pClone->m_TargetData.Copy(m_TargetData);
+ if (bRecursive) {
+ CloneChildren(pClone);
+ }
+ return pClone;
+}
+FX_INT32 CFDE_XMLInstruction::CountAttributes() const
+{
+ return m_Attributes.GetSize() / 2;
+}
+FX_BOOL CFDE_XMLInstruction::GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ FXSYS_assert(index > -1 && index < iCount / 2);
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (index == 0) {
+ wsAttriName = m_Attributes[i];
+ wsAttriValue = m_Attributes[i + 1];
+ return TRUE;
+ }
+ index --;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_XMLInstruction::HasAttribute(FX_LPCWSTR pwsAttriName) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+void CFDE_XMLInstruction::GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ wsAttriValue = m_Attributes[i + 1];
+ return;
+ }
+ }
+ wsAttriValue = pwsDefValue;
+}
+void CFDE_XMLInstruction::SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue)
+{
+ FXSYS_assert(wsAttriName.GetLength() > 0);
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(wsAttriName) == 0) {
+ m_Attributes[i] = wsAttriName;
+ m_Attributes[i + 1] = wsAttriValue;
+ return;
+ }
+ }
+ m_Attributes.Add(wsAttriName);
+ m_Attributes.Add(wsAttriValue);
+}
+FX_INT32 CFDE_XMLInstruction::GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return FXSYS_wtoi((FX_LPCWSTR)m_Attributes[i + 1]);
+ }
+ }
+ return iDefValue;
+}
+void CFDE_XMLInstruction::SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%d", iAttriValue);
+ SetString(pwsAttriName, wsValue);
+}
+FX_FLOAT CFDE_XMLInstruction::GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return FX_wcstof((FX_LPCWSTR)m_Attributes[i + 1]);
+ }
+ }
+ return fDefValue;
+}
+void CFDE_XMLInstruction::SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%f", fAttriValue);
+ SetString(pwsAttriName, wsValue);
+}
+void CFDE_XMLInstruction::RemoveAttribute(FX_LPCWSTR pwsAttriName)
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ m_Attributes.RemoveAt(i + 1);
+ m_Attributes.RemoveAt(i);
+ return;
+ }
+ }
+}
+FX_INT32 CFDE_XMLInstruction::CountData() const
+{
+ return m_TargetData.GetSize();
+}
+FX_BOOL CFDE_XMLInstruction::GetData(FX_INT32 index, CFX_WideString &wsData) const
+{
+ if (index < 0 || index >= m_TargetData.GetSize()) {
+ return FALSE;
+ }
+ wsData = m_TargetData[index];
+ return TRUE;
+}
+void CFDE_XMLInstruction::AppendData(const CFX_WideString &wsData)
+{
+ m_TargetData.Add(wsData);
+}
+void CFDE_XMLInstruction::RemoveData(FX_INT32 index)
+{
+ m_TargetData.RemoveAt(index);
+}
+IFDE_XMLElement* IFDE_XMLElement::Create(const CFX_WideString &wsTag)
+{
+ return (IFDE_XMLElement*)FDE_New CFDE_XMLElement(wsTag);
+}
+CFDE_XMLElement::CFDE_XMLElement(const CFX_WideString &wsTag)
+ : CFDE_XMLNode()
+ , m_wsTag(wsTag)
+ , m_Attributes()
+{
+ FXSYS_assert(m_wsTag.GetLength() > 0);
+}
+CFDE_XMLElement::~CFDE_XMLElement()
+{
+ m_Attributes.RemoveAll();
+}
+CFDE_XMLNode* CFDE_XMLElement::Clone(FX_BOOL bRecursive)
+{
+ CFDE_XMLElement* pClone = FDE_New CFDE_XMLElement(m_wsTag);
+ if (!pClone) {
+ return NULL;
+ }
+ pClone->m_Attributes.Copy(m_Attributes);
+ if (bRecursive) {
+ CloneChildren(pClone);
+ } else {
+ CFX_WideString wsText;
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ switch (pChild->GetType()) {
+ case FDE_XMLNODE_Text:
+ wsText += ((CFDE_XMLText*)pChild)->m_wsText;
+ break;
+ default:
+ break;
+ }
+ pChild = pChild->m_pNext;
+ }
+ pClone->SetTextData(wsText);
+ }
+ return pClone;
+}
+void CFDE_XMLElement::GetTagName(CFX_WideString &wsTag) const
+{
+ wsTag = m_wsTag;
+}
+void CFDE_XMLElement::GetLocalTagName(CFX_WideString &wsTag) const
+{
+ FX_STRSIZE iFind = m_wsTag.Find(L':', 0);
+ if (iFind < 0) {
+ wsTag = m_wsTag;
+ } else {
+ wsTag = m_wsTag.Right(m_wsTag.GetLength() - iFind - 1);
+ }
+}
+void CFDE_XMLElement::GetNamespacePrefix(CFX_WideString &wsPrefix) const
+{
+ FX_STRSIZE iFind = m_wsTag.Find(L':', 0);
+ if (iFind < 0) {
+ wsPrefix.Empty();
+ } else {
+ wsPrefix = m_wsTag.Left(iFind);
+ }
+}
+void CFDE_XMLElement::GetNamespaceURI(CFX_WideString &wsNamespace) const
+{
+ CFX_WideString wsAttri(L"xmlns"), wsPrefix;
+ GetNamespacePrefix(wsPrefix);
+ if (wsPrefix.GetLength() > 0) {
+ wsAttri += L":";
+ wsAttri += wsPrefix;
+ }
+ wsNamespace.Empty();
+ CFDE_XMLNode *pNode = (CFDE_XMLNode*)this;
+ while (pNode != NULL) {
+ if (pNode->GetType() != FDE_XMLNODE_Element) {
+ break;
+ }
+ CFDE_XMLElement *pElement = (CFDE_XMLElement*)pNode;
+ if (!pElement->HasAttribute(wsAttri)) {
+ pNode = pNode->GetNodeItem(IFDE_XMLNode::Parent);
+ continue;
+ }
+ pElement->GetString(wsAttri, wsNamespace);
+ break;
+ }
+}
+FX_INT32 CFDE_XMLElement::CountAttributes() const
+{
+ return m_Attributes.GetSize() / 2;
+}
+FX_BOOL CFDE_XMLElement::GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ FXSYS_assert(index > -1 && index < iCount / 2);
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (index == 0) {
+ wsAttriName = m_Attributes[i];
+ wsAttriValue = m_Attributes[i + 1];
+ return TRUE;
+ }
+ index --;
+ }
+ return FALSE;
+}
+FX_BOOL CFDE_XMLElement::HasAttribute(FX_LPCWSTR pwsAttriName) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+void CFDE_XMLElement::GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ wsAttriValue = m_Attributes[i + 1];
+ return;
+ }
+ }
+ wsAttriValue = pwsDefValue;
+}
+void CFDE_XMLElement::SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue)
+{
+ FXSYS_assert(wsAttriName.GetLength() > 0);
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(wsAttriName) == 0) {
+ m_Attributes[i] = wsAttriName;
+ m_Attributes[i + 1] = wsAttriValue;
+ return;
+ }
+ }
+ m_Attributes.Add(wsAttriName);
+ m_Attributes.Add(wsAttriValue);
+}
+FX_INT32 CFDE_XMLElement::GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return FXSYS_wtoi((FX_LPCWSTR)m_Attributes[i + 1]);
+ }
+ }
+ return iDefValue;
+}
+void CFDE_XMLElement::SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%d", iAttriValue);
+ SetString(pwsAttriName, wsValue);
+}
+FX_FLOAT CFDE_XMLElement::GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue) const
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ return FX_wcstof((FX_LPCWSTR)m_Attributes[i + 1]);
+ }
+ }
+ return fDefValue;
+}
+void CFDE_XMLElement::SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue)
+{
+ CFX_WideString wsValue;
+ wsValue.Format((FX_LPCWSTR)L"%f", fAttriValue);
+ SetString(pwsAttriName, wsValue);
+}
+void CFDE_XMLElement::RemoveAttribute(FX_LPCWSTR pwsAttriName)
+{
+ FX_INT32 iCount = m_Attributes.GetSize();
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ if (m_Attributes[i].Compare(pwsAttriName) == 0) {
+ m_Attributes.RemoveAt(i + 1);
+ m_Attributes.RemoveAt(i);
+ return;
+ }
+ }
+}
+void CFDE_XMLElement::GetTextData(CFX_WideString &wsText) const
+{
+ CFX_WideTextBuf buffer;
+ CFDE_XMLNode *pChild = m_pChild;
+ while (pChild != NULL) {
+ switch (pChild->GetType()) {
+ case FDE_XMLNODE_Text:
+ buffer << ((CFDE_XMLText*)pChild)->m_wsText;
+ break;
+ case FDE_XMLNODE_CharData:
+ buffer << ((CFDE_XMLCharData*)pChild)->m_wsCharData;
+ break;
+ default:
+ break;
+ }
+ pChild = pChild->m_pNext;
+ }
+ wsText = buffer.GetWideString();
+}
+void CFDE_XMLElement::SetTextData(const CFX_WideString &wsText)
+{
+ if (wsText.GetLength() < 1) {
+ return;
+ }
+ InsertChildNode(FDE_New CFDE_XMLText(wsText));
+}
+IFDE_XMLText* IFDE_XMLText::Create(const CFX_WideString &wsText)
+{
+ return (IFDE_XMLText*)FDE_New CFDE_XMLText(wsText);
+}
+CFDE_XMLText::CFDE_XMLText(const CFX_WideString &wsText)
+ : CFDE_XMLNode()
+ , m_wsText(wsText)
+{
+}
+CFDE_XMLNode* CFDE_XMLText::Clone(FX_BOOL bRecursive)
+{
+ CFDE_XMLText* pClone = FDE_New CFDE_XMLText(m_wsText);
+ return pClone;
+}
+IFDE_XMLCharData* IFDE_XMLCharData::Create(const CFX_WideString &wsCData)
+{
+ return (IFDE_XMLCharData*)FDE_New CFDE_XMLCharData(wsCData);
+}
+CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString &wsCData)
+ : CFDE_XMLDeclaration()
+ , m_wsCharData(wsCData)
+{
+}
+CFDE_XMLNode* CFDE_XMLCharData::Clone(FX_BOOL bRecursive)
+{
+ CFDE_XMLCharData* pClone = FDE_New CFDE_XMLCharData(m_wsCharData);
+ return pClone;
+}
+IFDE_XMLDoc* IFDE_XMLDoc::Create()
+{
+ return (IFDE_XMLDoc*)FDE_New CFDE_XMLDoc;
+}
+CFDE_XMLDoc::CFDE_XMLDoc()
+ : m_pRoot(NULL)
+ , m_pSyntaxParser(NULL)
+ , m_pXMLParser(NULL)
+{
+ Reset(TRUE);
+ CFDE_XMLInstruction *pXML = FDE_New CFDE_XMLInstruction((FX_LPCWSTR)L"xml");
+ m_pRoot->InsertChildNode(pXML);
+}
+CFDE_XMLDoc::~CFDE_XMLDoc()
+{
+ Reset(FALSE);
+}
+void CFDE_XMLDoc::Reset(FX_BOOL bInitRoot)
+{
+ m_iStatus = 0;
+ m_pStream = NULL;
+ if (bInitRoot) {
+ if (m_pRoot == NULL) {
+ m_pRoot = FDE_New CFDE_XMLNode;
+ } else {
+ m_pRoot->DeleteChildren();
+ }
+ } else {
+ if (m_pRoot != NULL) {
+ m_pRoot->Release();
+ m_pRoot = NULL;
+ }
+ }
+ ReleaseParser();
+}
+void CFDE_XMLDoc::ReleaseParser()
+{
+ if (m_pXMLParser != NULL) {
+ m_pXMLParser->Release();
+ m_pXMLParser = NULL;
+ }
+ if (m_pSyntaxParser != NULL) {
+ m_pSyntaxParser->Release();
+ m_pSyntaxParser = NULL;
+ }
+}
+FX_BOOL CFDE_XMLDoc::LoadXML(IFX_Stream *pXMLStream, FX_INT32 iXMLPlaneSize , FX_INT32 iTextDataSize , FDE_LPXMLREADERHANDLER pHandler )
+{
+ if (pXMLStream == NULL) {
+ return FALSE;
+ }
+ Reset(TRUE);
+ iXMLPlaneSize = iXMLPlaneSize / 1024;
+ if (iXMLPlaneSize < 1) {
+ iXMLPlaneSize = 1;
+ }
+ iXMLPlaneSize *= 1024;
+ if (iXMLPlaneSize < 4096) {
+ iXMLPlaneSize = 4096;
+ }
+ iTextDataSize = iTextDataSize / 128;
+ if (iTextDataSize < 1) {
+ iTextDataSize = 1;
+ }
+ iTextDataSize *= 128;
+ if (iTextDataSize < 128) {
+ iTextDataSize = 128;
+ }
+ m_pStream = pXMLStream;
+ FX_WORD wCodePage = m_pStream->GetCodePage();
+ if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && wCodePage != FX_CODEPAGE_UTF8) {
+ m_pStream->SetCodePage(FX_CODEPAGE_UTF8);
+ }
+ m_pSyntaxParser = IFDE_XMLSyntaxParser::Create();
+ if (m_pSyntaxParser == NULL) {
+ return FALSE;
+ }
+ m_pSyntaxParser->Init(m_pStream, iXMLPlaneSize, iTextDataSize);
+ if (pHandler == NULL) {
+ m_pXMLParser = FDE_New CFDE_XMLDOMParser(m_pRoot, m_pSyntaxParser);
+ } else {
+ m_pXMLParser = FDE_New CFDE_XMLSAXParser(pHandler, m_pSyntaxParser);
+ }
+ return m_pXMLParser != NULL;
+}
+FX_BOOL CFDE_XMLDoc::LoadXML(IFDE_XMLParser *pXMLParser)
+{
+ if (pXMLParser == NULL) {
+ return FALSE;
+ }
+ Reset(TRUE);
+ m_pXMLParser = pXMLParser;
+ return m_pXMLParser != NULL;
+}
+FX_INT32 CFDE_XMLDoc::DoLoad(IFX_Pause *pPause)
+{
+ if (m_iStatus >= 100) {
+ return m_iStatus;
+ }
+ FXSYS_assert(m_pXMLParser != NULL);
+ return m_iStatus = m_pXMLParser->DoParser(pPause);
+}
+void CFDE_XMLDoc::CloseXML()
+{
+ ReleaseParser();
+}
+void CFDE_XMLDoc::SaveXMLNode(IFX_Stream *pXMLStream, IFDE_XMLNode *pINode)
+{
+ CFDE_XMLNode *pNode = (CFDE_XMLNode*)pINode;
+ FXSYS_assert(pXMLStream != NULL && pNode != NULL);
+ switch (pNode->GetType()) {
+ case FDE_XMLNODE_Instruction: {
+ CFX_WideString ws;
+ CFDE_XMLInstruction *pInstruction = (CFDE_XMLInstruction*)pNode;
+ if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) {
+ ws = L"<?xml version=\"1.0\" encoding=\"";
+ FX_WORD wCodePage = pXMLStream->GetCodePage();
+ if (wCodePage == FX_CODEPAGE_UTF16LE) {
+ ws += L"UTF-16";
+ } else if (wCodePage == FX_CODEPAGE_UTF16BE) {
+ ws += L"UTF-16be";
+ } else {
+ ws += L"UTF-8";
+ }
+ ws += L"\"?>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ } else {
+ ws.Format((FX_LPCWSTR)L"<?%s", (FX_LPCWSTR)pInstruction->m_wsTarget);
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFX_WideStringArray &attributes = pInstruction->m_Attributes;
+ FX_INT32 i, iCount = attributes.GetSize();
+ CFX_WideString wsValue;
+ for (i = 0; i < iCount; i += 2) {
+ ws = L" ";
+ ws += attributes[i];
+ ws += L"=\"";
+ wsValue = attributes[i + 1];
+ wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ ws += wsValue;
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ CFX_WideStringArray &targetdata = pInstruction->m_TargetData;
+ iCount = targetdata.GetSize();
+ for (i = 0; i < iCount; i++) {
+ ws = L" \"";
+ ws += targetdata[i];
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ ws = L"?>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ }
+ break;
+ case FDE_XMLNODE_Element: {
+ CFX_WideString ws;
+ ws = L"<";
+ ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFX_WideStringArray &attributes = ((CFDE_XMLElement*)pNode)->m_Attributes;
+ FX_INT32 iCount = attributes.GetSize();
+ CFX_WideString wsValue;
+ for (FX_INT32 i = 0; i < iCount; i += 2) {
+ ws = L" ";
+ ws += attributes[i];
+ ws += L"=\"";
+ wsValue = attributes[i + 1];
+ wsValue.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ wsValue.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ wsValue.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ wsValue.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ wsValue.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ ws += wsValue;
+ ws += L"\"";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ if (pNode->m_pChild == NULL) {
+ ws = L"\n/>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ } else {
+ ws = L"\n>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ CFDE_XMLNode *pChild = pNode->m_pChild;
+ while (pChild != NULL) {
+ SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pChild);
+ pChild = pChild->m_pNext;
+ }
+ ws = L"</";
+ ws += ((CFDE_XMLElement*)pNode)->m_wsTag;
+ ws += L"\n>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ }
+ break;
+ case FDE_XMLNODE_Text: {
+ CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText;
+ ws.Replace((FX_LPCWSTR)L"&", (FX_LPCWSTR)L"&amp;");
+ ws.Replace((FX_LPCWSTR)L"<", (FX_LPCWSTR)L"&lt;");
+ ws.Replace((FX_LPCWSTR)L">", (FX_LPCWSTR)L"&gt;");
+ ws.Replace((FX_LPCWSTR)L"\'", (FX_LPCWSTR)L"&apos;");
+ ws.Replace((FX_LPCWSTR)L"\"", (FX_LPCWSTR)L"&quot;");
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ break;
+ case FDE_XMLNODE_CharData: {
+ CFX_WideString ws = L"<![CDATA[";
+ ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData;
+ ws += L"]]>";
+ pXMLStream->WriteString(ws, ws.GetLength());
+ }
+ break;
+ case FDE_XMLNODE_Unknown:
+ break;
+ default:
+ break;
+ }
+}
+void CFDE_XMLDoc::SaveXML(IFX_Stream *pXMLStream, FX_BOOL bSaveBOM)
+{
+ if (pXMLStream == NULL || pXMLStream == m_pStream) {
+ m_pStream->Seek(FX_STREAMSEEK_Begin, 0);
+ pXMLStream = m_pStream;
+ }
+ FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Text) != 0);
+ FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Write) != 0);
+ FX_WORD wCodePage = pXMLStream->GetCodePage();
+ if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && wCodePage != FX_CODEPAGE_UTF8) {
+ wCodePage = FX_CODEPAGE_UTF8;
+ pXMLStream->SetCodePage(wCodePage);
+ }
+ if (bSaveBOM) {
+ pXMLStream->WriteString((FX_LPCWSTR)L"\xFEFF", 1);
+ }
+ CFDE_XMLNode *pNode = m_pRoot->m_pChild;
+ while (pNode != NULL) {
+ SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pNode);
+ pNode = pNode->m_pNext;
+ }
+ if (pXMLStream == m_pStream) {
+ FX_INT32 iPos = pXMLStream->GetPosition();
+ pXMLStream->SetLength(iPos);
+ }
+}
+CFDE_XMLDOMParser::CFDE_XMLDOMParser(CFDE_XMLNode *pRoot, IFDE_XMLSyntaxParser *pParser)
+ : m_pRoot(pRoot)
+ , m_pParser(pParser)
+ , m_pParent(pRoot)
+ , m_pChild(NULL)
+ , m_NodeStack(16)
+ , m_ws1()
+ , m_ws2()
+{
+ m_NodeStack.Push(m_pParent);
+}
+CFDE_XMLDOMParser::~CFDE_XMLDOMParser()
+{
+ m_NodeStack.RemoveAll();
+ m_ws1.Empty();
+ m_ws2.Empty();
+}
+FX_INT32 CFDE_XMLDOMParser::DoParser(IFX_Pause *pPause)
+{
+ FX_DWORD dwRet;
+ FX_INT32 iCount = 0;
+ while (TRUE) {
+ dwRet = m_pParser->DoSyntaxParse();
+ switch (dwRet) {
+ case FDE_XMLSYNTAXSTATUS_InstructionOpen:
+ break;
+ case FDE_XMLSYNTAXSTATUS_InstructionClose:
+ if (m_pChild->GetType() != FDE_XMLNODE_Instruction) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pChild = m_pParent;
+ break;
+ case FDE_XMLSYNTAXSTATUS_ElementOpen:
+ case FDE_XMLSYNTAXSTATUS_ElementBreak:
+ break;
+ case FDE_XMLSYNTAXSTATUS_ElementClose:
+ if (m_pChild->GetType() != FDE_XMLNODE_Element) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pParser->GetTagName(m_ws1);
+ ((CFDE_XMLElement*)m_pChild)->GetTagName(m_ws2);
+ if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_ws2) != 0) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_NodeStack.Pop();
+ if (m_NodeStack.GetSize() < 1) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pParent = (CFDE_XMLNode*)*m_NodeStack.GetTopElement();
+ m_pChild = m_pParent;
+ iCount++;
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetName:
+ m_pParser->GetTargetName(m_ws1);
+ m_pChild = FDE_New CFDE_XMLInstruction(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_ws1.Empty();
+ break;
+ case FDE_XMLSYNTAXSTATUS_TagName:
+ m_pParser->GetTagName(m_ws1);
+ m_pChild = FDE_New CFDE_XMLElement(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_NodeStack.Push(m_pChild);
+ m_pParent = m_pChild;
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriName:
+ m_pParser->GetAttributeName(m_ws1);
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriValue:
+ if (m_pChild == NULL) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pParser->GetAttributeName(m_ws2);
+ if (m_pChild->GetType() == FDE_XMLNODE_Element) {
+ ((CFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2);
+ } else if (m_pChild->GetType() == FDE_XMLNODE_Instruction) {
+ ((CFDE_XMLInstruction*)m_pChild)->SetString(m_ws1, m_ws2);
+ }
+ m_ws1.Empty();
+ break;
+ case FDE_XMLSYNTAXSTATUS_Text:
+ m_pParser->GetTextData(m_ws1);
+ m_pChild = FDE_New CFDE_XMLText(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_pChild = m_pParent;
+ break;
+ case FDE_XMLSYNTAXSTATUS_CData:
+ m_pParser->GetTextData(m_ws1);
+ m_pChild = FDE_New CFDE_XMLCharData(m_ws1);
+ m_pParent->InsertChildNode(m_pChild);
+ m_pChild = m_pParent;
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetData:
+ if (m_pChild == NULL || m_pChild->GetType() != FDE_XMLNODE_Instruction) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ if (!m_ws1.IsEmpty()) {
+ ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
+ }
+ m_pParser->GetTargetData(m_ws1);
+ ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1);
+ m_ws1.Empty();
+ break;
+ default:
+ break;
+ }
+ if (dwRet == FDE_XMLSYNTAXSTATUS_Error || dwRet == FDE_XMLSYNTAXSTATUS_EOS) {
+ break;
+ }
+ if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) {
+ break;
+ }
+ }
+ return m_pParser->GetStatus();
+}
+CFDE_XMLSAXParser::CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, IFDE_XMLSyntaxParser *pParser)
+ : m_pHandler(pHandler)
+ , m_pParser(pParser)
+ , m_TagStack(16)
+ , m_pTagTop(NULL)
+ , m_ws1()
+ , m_ws2()
+{
+}
+CFDE_XMLSAXParser::~CFDE_XMLSAXParser()
+{
+ m_TagStack.RemoveAll();
+ m_ws1.Empty();
+ m_ws2.Empty();
+}
+FX_INT32 CFDE_XMLSAXParser::DoParser(IFX_Pause *pPause)
+{
+ FX_DWORD dwRet = 0;
+ FX_INT32 iCount = 0;
+ while (TRUE) {
+ dwRet = m_pParser->DoSyntaxParse();
+ switch (dwRet) {
+ case FDE_XMLSYNTAXSTATUS_ElementBreak:
+ if (m_pTagTop == NULL) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ if (m_pTagTop->eType == FDE_XMLNODE_Element) {
+ m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName);
+ }
+ break;
+ case FDE_XMLSYNTAXSTATUS_ElementClose:
+ if (m_pTagTop == NULL || m_pTagTop->eType != FDE_XMLNODE_Element) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ m_pParser->GetTagName(m_ws1);
+ if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_pTagTop->wsTagName) != 0) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ } else if (m_ws1.GetLength() == 0) {
+ m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName);
+ }
+ m_pHandler->OnTagClose(m_pHandler, m_pTagTop->wsTagName);
+ Pop();
+ iCount++;
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetName: {
+ m_pParser->GetTargetName(m_ws1);
+ CFDE_XMLTAG xmlTag;
+ xmlTag.wsTagName = m_ws1;
+ xmlTag.eType = FDE_XMLNODE_Instruction;
+ Push(xmlTag);
+ m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Instruction, m_pTagTop->wsTagName);
+ m_ws1.Empty();
+ }
+ break;
+ case FDE_XMLSYNTAXSTATUS_TagName: {
+ m_pParser->GetTargetName(m_ws1);
+ CFDE_XMLTAG xmlTag;
+ xmlTag.wsTagName = m_ws1;
+ xmlTag.eType = FDE_XMLNODE_Element;
+ Push(xmlTag);
+ m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Element, m_pTagTop->wsTagName);
+ }
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriName:
+ m_pParser->GetTargetName(m_ws1);
+ break;
+ case FDE_XMLSYNTAXSTATUS_AttriValue:
+ m_pParser->GetAttributeName(m_ws2);
+ if (m_pTagTop == NULL) {
+ dwRet = FDE_XMLSYNTAXSTATUS_Error;
+ break;
+ }
+ if (m_pTagTop->eType == FDE_XMLNODE_Element) {
+ m_pHandler->OnAttribute(m_pHandler, m_ws1, m_ws2);
+ }
+ m_ws1.Empty();
+ break;
+ case FDE_XMLSYNTAXSTATUS_CData:
+ m_pParser->GetTextData(m_ws1);
+ m_pHandler->OnData(m_pHandler, FDE_XMLNODE_CharData, m_ws1);
+ break;
+ case FDE_XMLSYNTAXSTATUS_Text:
+ m_pParser->GetTextData(m_ws1);
+ m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Text, m_ws1);
+ break;
+ case FDE_XMLSYNTAXSTATUS_TargetData:
+ m_pParser->GetTargetData(m_ws1);
+ m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Instruction, m_ws1);
+ m_ws1.Empty();
+ break;
+ default:
+ break;
+ }
+ if (dwRet == FDE_XMLSYNTAXSTATUS_Error || dwRet == FDE_XMLSYNTAXSTATUS_EOS) {
+ break;
+ }
+ if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) {
+ break;
+ }
+ }
+ return m_pParser->GetStatus();
+}
+inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG &xmlTag)
+{
+ m_TagStack.Push(xmlTag);
+ m_pTagTop = m_TagStack.GetTopElement();
+}
+inline void CFDE_XMLSAXParser::Pop()
+{
+ m_TagStack.Pop();
+ m_pTagTop = m_TagStack.GetTopElement();
+}
+#ifdef _FDE_BLOCK_BUFFER
+CFDE_BlockBuffer::CFDE_BlockBuffer(FX_INT32 iAllocStep)
+ : m_iAllocStep(iAllocStep),
+ m_iStartPosition(0),
+ m_iBufferSize(0),
+ m_iDataLength(0)
+{
+}
+CFDE_BlockBuffer::~CFDE_BlockBuffer()
+{
+ ClearBuffer();
+}
+FX_LPWSTR CFDE_BlockBuffer::GetAvailableBlock(FX_INT32& iIndexInBlock)
+{
+ iIndexInBlock = 0;
+ FX_INT32 iBlockNum = m_BlockArray.GetSize();
+ if (iBlockNum == 0) {
+ return NULL;
+ }
+ FX_INT32 iRealIndex = m_iStartPosition + m_iDataLength;
+ FX_LPWSTR pDataBlock = NULL;
+ if(iRealIndex == m_iBufferSize) {
+ FX_LPWSTR pBlock = (FX_LPWSTR)FDE_Alloc(m_iAllocStep * sizeof(FX_WCHAR));
+ if (pBlock) {
+ m_BlockArray.Add(pBlock);
+ m_iBufferSize += m_iAllocStep;
+ }
+ iIndexInBlock = 0;
+ pDataBlock = pBlock;
+ } else {
+ FX_INT32 iBlockIndex = iRealIndex / m_iAllocStep;
+ FX_INT32 iInnerIndex = iRealIndex % m_iAllocStep;
+ iIndexInBlock = iInnerIndex;
+ pDataBlock = (FX_LPWSTR)m_BlockArray[iBlockIndex];
+ }
+ return pDataBlock;
+}
+FX_BOOL CFDE_BlockBuffer::InitBuffer(FX_INT32 iBufferSize)
+{
+ ClearBuffer();
+ FX_INT32 iNumOfBlock = (iBufferSize - 1) / m_iAllocStep + 1;
+ for (FX_INT32 i = 0; i < iNumOfBlock; i++) {
+ FX_LPWSTR pBlockBuffer = (FX_LPWSTR)FDE_Alloc(m_iAllocStep * sizeof(FX_WCHAR));
+ if (pBlockBuffer == NULL) {
+ ClearBuffer();
+ return FALSE;
+ }
+ m_BlockArray.Add(pBlockBuffer);
+ }
+ m_iBufferSize = iNumOfBlock * m_iAllocStep;
+ return TRUE;
+}
+void CFDE_BlockBuffer::SetTextChar(FX_INT32 iIndex, FX_WCHAR ch)
+{
+ if (iIndex < 0) {
+ return;
+ }
+ FX_INT32 iRealIndex = m_iStartPosition + iIndex;
+ FX_INT32 iBlockIndex = iRealIndex / m_iAllocStep;
+ FX_INT32 iInnerIndex = iRealIndex % m_iAllocStep;
+ FX_INT32 iBlockSize = m_BlockArray.GetSize();
+ if (iBlockIndex >= iBlockSize) {
+ FX_INT32 iNewBlocks = iBlockIndex - iBlockSize + 1;
+ do {
+ FX_LPWSTR pBlock = (FX_LPWSTR)FDE_Alloc(m_iAllocStep * sizeof(FX_WCHAR));
+ if (!pBlock) {
+ return;
+ }
+ m_BlockArray.Add(pBlock);
+ m_iBufferSize += m_iAllocStep;
+ } while (--iNewBlocks);
+ }
+ FX_LPWSTR pTextData = (FX_LPWSTR)m_BlockArray[iBlockIndex];
+ *(pTextData + iInnerIndex) = ch;
+ if (m_iDataLength <= iIndex) {
+ m_iDataLength = iIndex + 1;
+ }
+}
+FX_INT32 CFDE_BlockBuffer::DeleteTextChars(FX_INT32 iCount, FX_BOOL bDirection )
+{
+ if (iCount <= 0) {
+ return m_iDataLength;
+ }
+ if (iCount >= m_iDataLength) {
+ Reset(FALSE);
+ return 0;
+ }
+ if (bDirection) {
+ m_iStartPosition += iCount;
+ m_iDataLength -= iCount;
+ } else {
+ m_iDataLength -= iCount;
+ }
+ return m_iDataLength;
+}
+void CFDE_BlockBuffer::GetTextData(CFX_WideString& wsTextData, FX_INT32 iStart, FX_INT32 iLength) const
+{
+ wsTextData.Empty();
+ FX_INT32 iMaybeDataLength = m_iBufferSize - 1 - m_iStartPosition;
+ if (iStart < 0 || iStart > iMaybeDataLength) {
+ return;
+ }
+ if (iLength == -1 || iLength > iMaybeDataLength) {
+ iLength = iMaybeDataLength;
+ }
+ if (iLength <= 0) {
+ return;
+ }
+ FX_LPWSTR pBuf = wsTextData.GetBuffer(iLength);
+ if (!pBuf) {
+ return;
+ }
+ FX_INT32 iStartBlockIndex = 0;
+ FX_INT32 iStartInnerIndex = 0;
+ TextDataIndex2BufIndex(iStart, iStartBlockIndex, iStartInnerIndex);
+ FX_INT32 iEndBlockIndex = 0;
+ FX_INT32 iEndInnerIndex = 0;
+ TextDataIndex2BufIndex(iStart + iLength, iEndBlockIndex, iEndInnerIndex);
+ FX_INT32 iPointer = 0;
+ for (FX_INT32 i = iStartBlockIndex; i <= iEndBlockIndex; i++) {
+ FX_INT32 iBufferPointer = 0;
+ FX_INT32 iCopyLength = m_iAllocStep;
+ if (i == iStartBlockIndex) {
+ iCopyLength -= iStartInnerIndex;
+ iBufferPointer = iStartInnerIndex;
+ }
+ if (i == iEndBlockIndex) {
+ iCopyLength -= ((m_iAllocStep - 1) - iEndInnerIndex);
+ }
+ FX_LPWSTR pBlockBuf = (FX_LPWSTR)m_BlockArray[i];
+ FXSYS_memcpy(pBuf + iPointer, pBlockBuf + iBufferPointer, iCopyLength * sizeof(FX_WCHAR));
+ iPointer += iCopyLength;
+ }
+ wsTextData.ReleaseBuffer(iLength);
+}
+void CFDE_BlockBuffer::TextDataIndex2BufIndex(const FX_INT32 iIndex, FX_INT32& iBlockIndex, FX_INT32& iInnerIndex) const
+{
+ FXSYS_assert(iIndex >= 0);
+ FX_INT32 iRealIndex = m_iStartPosition + iIndex;
+ iBlockIndex = iRealIndex / m_iAllocStep;
+ iInnerIndex = iRealIndex % m_iAllocStep;
+}
+void CFDE_BlockBuffer::ClearBuffer()
+{
+ m_iBufferSize = 0;
+ FX_INT32 iSize = m_BlockArray.GetSize();
+ for (FX_INT32 i = 0; i < iSize; i++) {
+ FDE_Free(m_BlockArray[i]);
+ m_BlockArray[i] = NULL;
+ }
+ m_BlockArray.RemoveAll();
+}
+#endif
+IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create()
+{
+ return FDE_New CFDE_XMLSyntaxParser;
+}
+#ifdef _FDE_BLOCK_BUFFER
+CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser()
+ : m_pStream(NULL)
+ , m_iXMLPlaneSize(-1)
+ , m_iCurrentPos(0)
+ , m_iCurrentNodeNum(-1)
+ , m_iLastNodeNum(-1)
+ , m_iParsedChars(0)
+ , m_iParsedBytes(0)
+ , m_pBuffer(NULL)
+ , m_iBufferChars(0)
+ , m_bEOS(FALSE)
+ , m_pStart(NULL)
+ , m_pEnd(NULL)
+ , m_XMLNodeStack(16)
+ , m_dwStatus(FDE_XMLSYNTAXSTATUS_None)
+ , m_dwMode(FDE_XMLSYNTAXMODE_Text)
+ , m_wQuotationMark(0)
+ , m_BlockBuffer()
+ , m_pCurrentBlock(NULL)
+ , m_iIndexInBlock(0)
+ , m_iDataLength(m_BlockBuffer.GetDataLengthRef())
+ , m_iAllocStep(m_BlockBuffer.GetAllocStep())
+ , m_iTextDataLength(0)
+ , m_iEntityStart(-1)
+ , m_SkipStack(16)
+{
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+}
+void CFDE_XMLSyntaxParser::Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize )
+{
+ FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL);
+ FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0);
+ FX_INT32 iStreamLength = pStream->GetLength();
+ FXSYS_assert(iStreamLength > 0);
+ m_pStream = pStream;
+ m_iXMLPlaneSize = FX_MIN(iXMLPlaneSize, iStreamLength);
+ FX_BYTE bom[4];
+ m_iCurrentPos = m_pStream->GetBOM(bom);
+ FXSYS_assert(m_pBuffer == NULL);
+ m_pBuffer = (FX_LPWSTR)FDE_Alloc(m_iXMLPlaneSize * sizeof(FX_WCHAR));
+ m_pStart = m_pEnd = m_pBuffer;
+ FXSYS_assert(!m_BlockBuffer.IsInitialized());
+ m_BlockBuffer.InitBuffer();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_iParsedBytes = m_iParsedChars = 0;
+ m_iBufferChars = 0;
+}
+FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse()
+{
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+ return m_dwStatus;
+ }
+ FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_BlockBuffer.IsInitialized());
+ FX_INT32 iStreamLength = m_pStream->GetLength();
+ FX_INT32 iPos;
+ FX_WCHAR ch;
+ FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None;
+ while (TRUE) {
+ if (m_pStart >= m_pEnd) {
+ if (m_bEOS || m_iCurrentPos >= iStreamLength) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
+ return m_dwStatus;
+ }
+ m_iParsedChars += (m_pEnd - m_pBuffer);
+ m_iParsedBytes = m_iCurrentPos;
+ m_pStream->Lock();
+ if (m_pStream->GetPosition() != m_iCurrentPos) {
+ m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos);
+ }
+ m_iBufferChars = m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS);
+ iPos = m_pStream->GetPosition();
+ m_pStream->Unlock();
+ if (m_iBufferChars < 1) {
+ m_iCurrentPos = iStreamLength;
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
+ return m_dwStatus;
+ }
+ m_iCurrentPos = iPos;
+ m_pStart = m_pBuffer;
+ m_pEnd = m_pBuffer + m_iBufferChars;
+ }
+ while (m_pStart < m_pEnd) {
+ ch = *m_pStart;
+ switch (m_dwMode) {
+ case FDE_XMLSYNTAXMODE_Text:
+ if (ch == L'<') {
+ if (m_iDataLength > 0) {
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_iEntityStart = -1;
+ dwStatus = FDE_XMLSYNTAXSTATUS_Text;
+ } else {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_Node;
+ }
+ } else {
+ ParseTextChar(ch);
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_Node:
+ if (ch == L'!') {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl;
+ } else if (ch == L'/') {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
+ } else if (ch == L'?') {
+ m_iLastNodeNum ++;
+ m_iCurrentNodeNum = m_iLastNodeNum;
+ m_CurNode.iNodeNum = m_iLastNodeNum;
+ m_CurNode.eNodeType = FDE_XMLNODE_Instruction;
+ m_XMLNodeStack.Push(m_CurNode);
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_Target;
+ dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen;
+ } else {
+ m_iLastNodeNum ++;
+ m_iCurrentNodeNum = m_iLastNodeNum;
+ m_CurNode.iNodeNum = m_iLastNodeNum;
+ m_CurNode.eNodeType = FDE_XMLNODE_Element;
+ m_XMLNodeStack.Push(m_CurNode);
+ m_dwMode = FDE_XMLSYNTAXMODE_Tag;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_Target:
+ case FDE_XMLSYNTAXMODE_Tag:
+ if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) {
+ if (m_iDataLength < 1) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (m_dwMode != FDE_XMLSYNTAXMODE_Target) {
+ dwStatus = FDE_XMLSYNTAXSTATUS_TagName;
+ } else {
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetName;
+ }
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
+ }
+ } else {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriName:
+ if (m_iDataLength < 1 && FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) {
+ if (m_iDataLength < 1) {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Element) {
+ if (ch == L'>' || ch == L'/') {
+ m_dwMode = FDE_XMLSYNTAXMODE_BreakElement;
+ break;
+ }
+ } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ if (ch == L'?') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
+ m_pStart++;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ }
+ break;
+ }
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ break;
+ }
+ }
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign;
+ dwStatus = FDE_XMLSYNTAXSTATUS_AttriName;
+ }
+ } else {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriEqualSign:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (ch != L'=') {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ break;
+ }
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriQuotation:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (ch != L'\"' && ch != L'\'') {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_wQuotationMark = ch;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriValue;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriValue:
+ if (ch == m_wQuotationMark) {
+ if (m_iEntityStart > -1) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_iTextDataLength = m_iDataLength;
+ m_wQuotationMark = 0;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
+ dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue;
+ } else {
+ ParseTextChar(ch);
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_CloseInstruction:
+ if (ch != L'>') {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ } else if (m_iDataLength > 0) {
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ } else {
+ m_pStart ++;
+ FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_XMLNodeStack.Pop();
+ pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+ } else {
+ m_CurNode = *pXMLNode;
+ }
+ m_iCurrentNodeNum = m_CurNode.iNodeNum;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_BreakElement:
+ if (ch == L'>') {
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak;
+ } else if (ch == L'/') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
+ } else {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_pStart ++;
+ break;
+ case FDE_XMLSYNTAXMODE_CloseElement:
+ if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) {
+ if (ch == L'>') {
+ FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_XMLNodeStack.Pop();
+ pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+ } else {
+ m_CurNode = *pXMLNode;
+ }
+ m_iCurrentNodeNum = m_CurNode.iNodeNum;
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose;
+ } else if (!FDE_IsXMLWhiteSpace(ch)) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ } else {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ }
+ m_pStart ++;
+ break;
+ case FDE_XMLSYNTAXMODE_SkipCommentOrDecl:
+ if (ch == '-') {
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipComment;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode;
+ m_SkipChar = L'>';
+ m_SkipStack.Push(L'>');
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_SkipDeclNode:
+ if (m_SkipChar == L'\'' || m_SkipChar == L'\"') {
+ m_pStart ++;
+ if (ch != m_SkipChar) {
+ break;
+ }
+ m_SkipStack.Pop();
+ FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
+ if (pDWord == NULL) {
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ } else {
+ m_SkipChar = (FX_WCHAR) * pDWord;
+ }
+ } else {
+ switch (ch) {
+ case L'<':
+ m_SkipChar = L'>';
+ m_SkipStack.Push(L'>');
+ break;
+ case L'[':
+ m_SkipChar = L']';
+ m_SkipStack.Push(L']');
+ break;
+ case L'(':
+ m_SkipChar = L')';
+ m_SkipStack.Push(L')');
+ break;
+ case L'\'':
+ m_SkipChar = L'\'';
+ m_SkipStack.Push(L'\'');
+ break;
+ case L'\"':
+ m_SkipChar = L'\"';
+ m_SkipStack.Push(L'\"');
+ break;
+ default:
+ if (ch == m_SkipChar) {
+ m_SkipStack.Pop();
+ FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
+ if (pDWord == NULL) {
+ if (m_iDataLength >= 9) {
+ CFX_WideString wsHeader;
+ m_BlockBuffer.GetTextData(wsHeader, 0, 7);
+ if (wsHeader.Equal(FX_WSTRC(L"[CDATA["))) {
+ CFX_WideString wsTailer;
+ m_BlockBuffer.GetTextData(wsTailer, m_iDataLength - 2, 2);
+ if (wsTailer.Equal(FX_WSTRC(L"]]"))) {
+ m_BlockBuffer.DeleteTextChars(7, TRUE);
+ m_BlockBuffer.DeleteTextChars(2, FALSE);
+ dwStatus = FDE_XMLSYNTAXSTATUS_CData;
+ }
+ }
+ }
+ m_iTextDataLength = m_iDataLength;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ } else {
+ m_SkipChar = (FX_WCHAR) * pDWord;
+ }
+ }
+ break;
+ }
+ if (m_SkipStack.GetSize() > 0) {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ }
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_SkipComment:
+ if (ch == L'-') {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = L'-';
+ m_iDataLength++;
+ } else if (ch == L'>') {
+ if (m_iDataLength > 1) {
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ }
+ } else {
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ }
+ m_pStart++;
+ break;
+ case FDE_XMLSYNTAXMODE_TargetData:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ if (m_iDataLength < 1) {
+ m_pStart ++;
+ break;
+ } else if (m_wQuotationMark == 0) {
+ m_iTextDataLength = m_iDataLength;
+ m_wQuotationMark = 0;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_pStart ++;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ break;
+ }
+ }
+ if (ch == '?') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
+ m_pStart++;
+ } else if (ch == '\"') {
+ if (m_wQuotationMark == 0) {
+ m_wQuotationMark = ch;
+ m_pStart++;
+ } else if (ch == m_wQuotationMark) {
+ m_iTextDataLength = m_iDataLength;
+ m_wQuotationMark = 0;
+ m_BlockBuffer.Reset();
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_pStart ++;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ } else {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ } else {
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return FDE_XMLSYNTAXSTATUS_Error;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ m_pStart ++;
+ }
+ break;
+ default:
+ break;
+ }
+ if (dwStatus != FDE_XMLSYNTAXSTATUS_None) {
+ return dwStatus;
+ }
+ }
+ }
+ return 0;
+}
+#else
+CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser()
+ : m_pStream(NULL)
+ , m_iXMLPlaneSize(-1)
+ , m_iTextDataSize(256)
+ , m_iCurrentPos(0)
+ , m_iCurrentNodeNum(-1)
+ , m_iLastNodeNum(-1)
+ , m_iParsedChars(0)
+ , m_iParsedBytes(0)
+ , m_pBuffer(NULL)
+ , m_iBufferChars(0)
+ , m_bEOS(FALSE)
+ , m_pStart(NULL)
+ , m_pEnd(NULL)
+ , m_XMLNodeStack(16)
+ , m_pwsTextData(NULL)
+ , m_iDataPos(0)
+ , m_dwStatus(FDE_XMLSYNTAXSTATUS_None)
+ , m_dwMode(FDE_XMLSYNTAXMODE_Text)
+ , m_wQuotationMark(0)
+ , m_iTextDataLength(0)
+ , m_iEntityStart(-1)
+ , m_SkipStack(16)
+{
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+}
+void CFDE_XMLSyntaxParser::Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize )
+{
+ FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL);
+ FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0 && iTextDataSize > 0);
+ FX_INT32 iStreamLength = pStream->GetLength();
+ FXSYS_assert(iStreamLength > 0);
+ m_pStream = pStream;
+ m_iXMLPlaneSize = FX_MIN(iXMLPlaneSize, iStreamLength);
+ m_iTextDataSize = iTextDataSize;
+ FX_BYTE bom[4];
+ m_iCurrentPos = m_pStream->GetBOM(bom);
+ FXSYS_assert(m_pBuffer == NULL);
+ m_pBuffer = (FX_LPWSTR)FDE_Alloc(m_iXMLPlaneSize * sizeof(FX_WCHAR));
+ m_pStart = m_pEnd = m_pBuffer;
+ FXSYS_assert(m_pwsTextData == NULL);
+ m_pwsTextData = (FX_LPWSTR)FDE_Alloc(m_iTextDataSize * sizeof(FX_WCHAR));
+ m_iParsedBytes = m_iParsedChars = 0;
+ m_iBufferChars = 0;
+}
+FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse()
+{
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+ return m_dwStatus;
+ }
+ FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_pwsTextData != NULL);
+ FX_INT32 iStreamLength = m_pStream->GetLength();
+ FX_INT32 iPos;
+ FX_WCHAR ch;
+ FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None;
+ while (TRUE) {
+ if (m_pStart >= m_pEnd) {
+ if (m_bEOS || m_iCurrentPos >= iStreamLength) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
+ return m_dwStatus;
+ }
+ m_iParsedChars += (m_pEnd - m_pBuffer);
+ m_iParsedBytes = m_iCurrentPos;
+ m_pStream->Lock();
+ if (m_pStream->GetPosition() != m_iCurrentPos) {
+ m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos);
+ }
+ m_iBufferChars = m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS);
+ iPos = m_pStream->GetPosition();
+ m_pStream->Unlock();
+ if (m_iBufferChars < 1) {
+ m_iCurrentPos = iStreamLength;
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS;
+ return m_dwStatus;
+ }
+ m_iCurrentPos = iPos;
+ m_pStart = m_pBuffer;
+ m_pEnd = m_pBuffer + m_iBufferChars;
+ }
+ while (m_pStart < m_pEnd) {
+ ch = *m_pStart;
+ switch (m_dwMode) {
+ case FDE_XMLSYNTAXMODE_Text:
+ if (ch == L'<') {
+ if (m_iDataPos > 0) {
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ m_iEntityStart = -1;
+ dwStatus = FDE_XMLSYNTAXSTATUS_Text;
+ } else {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_Node;
+ }
+ } else {
+ ParseTextChar(ch);
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_Node:
+ if (ch == L'!') {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl;
+ } else if (ch == L'/') {
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
+ } else if (ch == L'?') {
+ m_iLastNodeNum ++;
+ m_iCurrentNodeNum = m_iLastNodeNum;
+ m_CurNode.iNodeNum = m_iLastNodeNum;
+ m_CurNode.eNodeType = FDE_XMLNODE_Instruction;
+ m_XMLNodeStack.Push(m_CurNode);
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_Target;
+ dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen;
+ } else {
+ m_iLastNodeNum ++;
+ m_iCurrentNodeNum = m_iLastNodeNum;
+ m_CurNode.iNodeNum = m_iLastNodeNum;
+ m_CurNode.eNodeType = FDE_XMLNODE_Element;
+ m_XMLNodeStack.Push(m_CurNode);
+ m_dwMode = FDE_XMLSYNTAXMODE_Tag;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_Target:
+ case FDE_XMLSYNTAXMODE_Tag:
+ if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) {
+ if (m_iDataPos < 1) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_dwMode != FDE_XMLSYNTAXMODE_Target) {
+ dwStatus = FDE_XMLSYNTAXSTATUS_TagName;
+ } else {
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetName;
+ }
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
+ }
+ } else {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriName:
+ if (m_iDataPos < 1 && FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) {
+ if (m_iDataPos < 1) {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Element) {
+ if (ch == L'>' || ch == L'/') {
+ m_dwMode = FDE_XMLSYNTAXMODE_BreakElement;
+ break;
+ }
+ } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ if (ch == L'?') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
+ m_pStart++;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ }
+ break;
+ }
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ break;
+ }
+ }
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign;
+ dwStatus = FDE_XMLSYNTAXSTATUS_AttriName;
+ }
+ } else {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriEqualSign:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (ch != L'=') {
+ if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) {
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ break;
+ }
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriQuotation:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ m_pStart ++;
+ break;
+ }
+ if (ch != L'\"' && ch != L'\'') {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ } else {
+ m_wQuotationMark = ch;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriValue;
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_AttriValue:
+ if (ch == m_wQuotationMark) {
+ if (m_iEntityStart > -1) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_iTextDataLength = m_iDataPos;
+ m_wQuotationMark = 0;
+ m_iDataPos = 0;
+ m_pStart ++;
+ m_dwMode = FDE_XMLSYNTAXMODE_AttriName;
+ dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue;
+ } else {
+ ParseTextChar(ch);
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_CloseInstruction:
+ if (ch != L'>') {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ m_dwMode = FDE_XMLSYNTAXMODE_TargetData;
+ } else if (m_iDataPos > 0) {
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ } else {
+ m_pStart ++;
+ FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_XMLNodeStack.Pop();
+ pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+ } else {
+ m_CurNode = *pXMLNode;
+ }
+ m_iCurrentNodeNum = m_CurNode.iNodeNum;
+ m_iDataPos = 0;
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_BreakElement:
+ if (ch == L'>') {
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak;
+ } else if (ch == L'/') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseElement;
+ } else {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_pStart ++;
+ break;
+ case FDE_XMLSYNTAXMODE_CloseElement:
+ if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) {
+ if (ch == L'>') {
+ FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ m_XMLNodeStack.Pop();
+ pXMLNode = m_XMLNodeStack.GetTopElement();
+ if (pXMLNode == NULL) {
+ m_CurNode.iNodeNum = -1;
+ m_CurNode.eNodeType = FDE_XMLNODE_Unknown;
+ } else {
+ m_CurNode = *pXMLNode;
+ }
+ m_iCurrentNodeNum = m_CurNode.iNodeNum;
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose;
+ } else if (!FDE_IsXMLWhiteSpace(ch)) {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ } else {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ }
+ m_pStart ++;
+ break;
+ case FDE_XMLSYNTAXMODE_SkipCommentOrDecl:
+ if (ch == '-') {
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipComment;
+ } else {
+ m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode;
+ m_SkipChar = L'>';
+ m_SkipStack.Push(L'>');
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_SkipDeclNode:
+ if (m_SkipChar == L'\'' || m_SkipChar == L'\"') {
+ m_pStart ++;
+ if (ch != m_SkipChar) {
+ break;
+ }
+ m_SkipStack.Pop();
+ FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
+ if (pDWord == NULL) {
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ } else {
+ m_SkipChar = (FX_WCHAR) * pDWord;
+ }
+ } else {
+ switch (ch) {
+ case L'<':
+ m_SkipChar = L'>';
+ m_SkipStack.Push(L'>');
+ break;
+ case L'[':
+ m_SkipChar = L']';
+ m_SkipStack.Push(L']');
+ break;
+ case L'(':
+ m_SkipChar = L')';
+ m_SkipStack.Push(L')');
+ break;
+ case L'\'':
+ m_SkipChar = L'\'';
+ m_SkipStack.Push(L'\'');
+ break;
+ case L'\"':
+ m_SkipChar = L'\"';
+ m_SkipStack.Push(L'\"');
+ break;
+ default:
+ if (ch == m_SkipChar) {
+ m_SkipStack.Pop();
+ FX_LPDWORD pDWord = m_SkipStack.GetTopElement();
+ if (pDWord == NULL) {
+ m_iTextDataLength = m_iDataPos;
+ m_iDataPos = 0;
+ if (m_iTextDataLength >= 9
+ && FXSYS_memcmp(m_pwsTextData, L"[CDATA[", 7 * sizeof(FX_WCHAR)) == 0
+ && FXSYS_memcmp(m_pwsTextData + m_iTextDataLength - 2, L"]]", 2 * sizeof(FX_WCHAR)) == 0) {
+ m_iTextDataLength -= 9;
+ FXSYS_memmove(m_pwsTextData, m_pwsTextData + 7, m_iTextDataLength * sizeof(FX_WCHAR));
+ dwStatus = FDE_XMLSYNTAXSTATUS_CData;
+ }
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ } else {
+ m_SkipChar = (FX_WCHAR) * pDWord;
+ }
+ }
+ break;
+ }
+ if (m_SkipStack.GetSize() > 0) {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ }
+ m_pStart ++;
+ }
+ break;
+ case FDE_XMLSYNTAXMODE_SkipComment:
+ if (ch == L'-') {
+ m_iDataPos++;
+ } else if (ch == L'>') {
+ if (m_iDataPos > 1) {
+ m_iDataPos = 0;
+ m_dwMode = FDE_XMLSYNTAXMODE_Text;
+ }
+ } else {
+ m_iDataPos = 0;
+ }
+ m_pStart++;
+ break;
+ case FDE_XMLSYNTAXMODE_TargetData:
+ if (FDE_IsXMLWhiteSpace(ch)) {
+ if (m_iDataPos < 1) {
+ m_pStart ++;
+ break;
+ } else if (m_wQuotationMark == 0) {
+ m_iTextDataLength = m_iDataPos;
+ m_wQuotationMark = 0;
+ m_iDataPos = 0;
+ m_pStart ++;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ break;
+ }
+ }
+ if (ch == '?') {
+ m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction;
+ m_pStart++;
+ } else if (ch == '\"') {
+ if (m_wQuotationMark == 0) {
+ m_wQuotationMark = ch;
+ m_pStart++;
+ } else if (ch == m_wQuotationMark) {
+ m_iTextDataLength = m_iDataPos;
+ m_wQuotationMark = 0;
+ m_iDataPos = 0;
+ m_pStart ++;
+ dwStatus = FDE_XMLSYNTAXSTATUS_TargetData;
+ } else {
+ m_dwStatus = FDE_XMLSYNTAXSTATUS_Error;
+ return m_dwStatus;
+ }
+ } else {
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos ++] = ch;
+ m_pStart ++;
+ }
+ break;
+ default:
+ break;
+ }
+ if (dwStatus != FDE_XMLSYNTAXSTATUS_None) {
+ return dwStatus;
+ }
+ }
+ }
+ return 0;
+}
+#endif
+CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser()
+{
+#ifdef _FDE_BLOCK_BUFFER
+ if (m_pCurrentBlock) {
+ m_pCurrentBlock = NULL;
+ }
+#else
+ if (m_pwsTextData != NULL) {
+ FDE_Free(m_pwsTextData);
+ }
+#endif
+ if (m_pBuffer != NULL) {
+ FDE_Free(m_pBuffer);
+ }
+}
+FX_INT32 CFDE_XMLSyntaxParser::GetStatus() const
+{
+ if (m_pStream == NULL) {
+ return -1;
+ }
+ FX_INT32 iStreamLength = m_pStream->GetLength();
+ if (iStreamLength < 1) {
+ return 100;
+ }
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) {
+ return -1;
+ }
+ if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) {
+ return 100;
+ }
+ return m_iParsedBytes * 100 / iStreamLength;
+}
+static FX_INT32 FX_GetUTF8EncodeLength(FX_LPCWSTR pSrc, FX_INT32 iSrcLen)
+{
+ FX_DWORD unicode = 0;
+ FX_INT32 iDstNum = 0;
+ while (iSrcLen -- > 0) {
+ unicode = *pSrc ++;
+ int nbytes = 0;
+ if ((FX_DWORD)unicode < 0x80) {
+ nbytes = 1;
+ } else if ((FX_DWORD)unicode < 0x800) {
+ nbytes = 2;
+ } else if ((FX_DWORD)unicode < 0x10000) {
+ nbytes = 3;
+ } else if ((FX_DWORD)unicode < 0x200000) {
+ nbytes = 4;
+ } else if ((FX_DWORD)unicode < 0x4000000) {
+ nbytes = 5;
+ } else {
+ nbytes = 6;
+ }
+ iDstNum += nbytes;
+ }
+ return iDstNum;
+}
+FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const
+{
+ if (m_pStream == NULL) {
+ return 0;
+ }
+ FX_INT32 nSrcLen = m_pStart - m_pBuffer;
+ FX_INT32 nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen);
+ return m_iParsedBytes + nDstLen;
+}
+#ifdef _FDE_BLOCK_BUFFER
+void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch)
+{
+ if (m_iIndexInBlock == m_iAllocStep) {
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ if (!m_pCurrentBlock) {
+ return;
+ }
+ }
+ m_pCurrentBlock[m_iIndexInBlock++] = ch;
+ m_iDataLength++;
+ if (m_iEntityStart > -1 && ch == L';') {
+ CFX_WideString csEntity;
+ m_BlockBuffer.GetTextData(csEntity, m_iEntityStart + 1, (m_iDataLength - 1) - m_iEntityStart - 1);
+ FX_INT32 iLen = csEntity.GetLength();
+ if (iLen > 0) {
+ if (csEntity[0] == L'#') {
+ ch = 0;
+ FX_WCHAR w;
+ if (iLen > 1 && csEntity[1] == L'x') {
+ for (FX_INT32 i = 2; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w >= L'0' && w <= L'9') {
+ ch = (ch << 4) + w - L'0';
+ } else if (w >= L'A' && w <= L'F') {
+ ch = (ch << 4) + w - 55;
+ } else if (w >= L'a' && w <= L'f') {
+ ch = (ch << 4) + w - 87;
+ } else {
+ break;
+ }
+ }
+ } else {
+ for (FX_INT32 i = 1; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w < L'0' || w > L'9') {
+ break;
+ }
+ ch = ch * 10 + w - L'0';
+ }
+ }
+ if (ch != 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, ch);
+ m_iEntityStart ++;
+ }
+ } else {
+ if (csEntity.Compare(L"amp") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'&');
+ m_iEntityStart ++;
+ } else if (csEntity.Compare(L"lt") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'<');
+ m_iEntityStart ++;
+ } else if (csEntity.Compare(L"gt") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'>');
+ m_iEntityStart ++;
+ } else if (csEntity.Compare(L"apos") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'\'');
+ m_iEntityStart ++;
+ } else if (csEntity.Compare(L"quot") == 0) {
+ m_BlockBuffer.SetTextChar(m_iEntityStart, L'\"');
+ m_iEntityStart ++;
+ }
+ }
+ }
+ m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE);
+ m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock);
+ m_iEntityStart = -1;
+ } else {
+ if (m_iEntityStart < 0 && ch == L'&') {
+ m_iEntityStart = m_iDataLength - 1;
+ }
+ }
+ m_pStart ++;
+}
+#else
+void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch)
+{
+ if (m_iDataPos >= m_iTextDataSize) {
+ ReallocTextDataBuffer();
+ }
+ m_pwsTextData[m_iDataPos] = ch;
+ if (m_iEntityStart > -1 && ch == L';') {
+ CFX_WideString csEntity(m_pwsTextData + m_iEntityStart + 1, m_iDataPos - m_iEntityStart - 1);
+ FX_INT32 iLen = csEntity.GetLength();
+ if (iLen > 0) {
+ if (csEntity[0] == L'#') {
+ ch = 0;
+ FX_WCHAR w;
+ if (iLen > 1 && csEntity[1] == L'x') {
+ for (FX_INT32 i = 2; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w >= L'0' && w <= L'9') {
+ ch = (ch << 4) + w - L'0';
+ } else if (w >= L'A' && w <= L'F') {
+ ch = (ch << 4) + w - 55;
+ } else if (w >= L'a' && w <= L'f') {
+ ch = (ch << 4) + w - 87;
+ } else {
+ break;
+ }
+ }
+ } else {
+ for (FX_INT32 i = 1; i < iLen; i ++) {
+ w = csEntity[i];
+ if (w < L'0' || w > L'9') {
+ break;
+ }
+ ch = ch * 10 + w - L'0';
+ }
+ }
+ if (ch != 0) {
+ m_pwsTextData[m_iEntityStart ++] = ch;
+ }
+ } else {
+ if (csEntity.Compare(L"amp") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'&';
+ } else if (csEntity.Compare(L"lt") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'<';
+ } else if (csEntity.Compare(L"gt") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'>';
+ } else if (csEntity.Compare(L"apos") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'\'';
+ } else if (csEntity.Compare(L"quot") == 0) {
+ m_pwsTextData[m_iEntityStart ++] = L'\"';
+ }
+ }
+ }
+ m_iDataPos = m_iEntityStart;
+ m_iEntityStart = -1;
+ } else {
+ if (m_iEntityStart < 0 && ch == L'&') {
+ m_iEntityStart = m_iDataPos;
+ }
+ m_iDataPos ++;
+ }
+ m_pStart ++;
+}
+void CFDE_XMLSyntaxParser::ReallocTextDataBuffer()
+{
+ FXSYS_assert(m_pwsTextData != NULL);
+ if (m_iTextDataSize <= 1024 * 1024) {
+ m_iTextDataSize *= 2;
+ } else {
+ m_iTextDataSize += 1024 * 1024;
+ }
+ m_pwsTextData = (FX_LPWSTR)FDE_Realloc(m_pwsTextData, m_iTextDataSize * sizeof(FX_WCHAR));
+}
+void CFDE_XMLSyntaxParser::GetData(CFX_WideString &wsData) const
+{
+ FX_LPWSTR pBuf = wsData.GetBuffer(m_iTextDataLength);
+ FXSYS_memcpy(pBuf, m_pwsTextData, m_iTextDataLength * sizeof(FX_WCHAR));
+ wsData.ReleaseBuffer(m_iTextDataLength);
+}
+#endif
diff --git a/xfa/src/fdp/src/xml/fde_xml.h b/xfa/src/fdp/src/xml/fde_xml.h
new file mode 100644
index 0000000000..edbf01584a
--- /dev/null
+++ b/xfa/src/fdp/src/xml/fde_xml.h
@@ -0,0 +1,443 @@
+// Copyright 2014 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#ifndef _FDE_XML_IMP
+#define _FDE_XML_IMP
+#define _FDE_BLOCK_BUFFER
+#ifdef _FDE_BLOCK_BUFFER
+class CFDE_BlockBuffer;
+#endif
+class CFDE_XMLNode;
+class CFDE_XMLInstruction;
+class CFDE_XMLElement;
+class CFDE_XMLText;
+class CFDE_XMLDoc;
+class IFDE_XMLParser;
+class CFDE_XMLDOMParser;
+class CFDE_XMLSAXParser;
+class CFDE_XMLSyntaxParser;
+class CFDE_XMLNode : public CFX_Target
+{
+public:
+ CFDE_XMLNode();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_Unknown;
+ }
+ virtual FX_INT32 CountChildNodes() const;
+ virtual CFDE_XMLNode* GetChildNode(FX_INT32 index) const;
+ virtual FX_INT32 GetChildNodeIndex(CFDE_XMLNode *pNode) const;
+ virtual CFDE_XMLNode* GetPath(FX_LPCWSTR pPath, FX_INT32 iLength = -1, FX_BOOL bQualifiedName = TRUE) const;
+ virtual FX_INT32 InsertChildNode(CFDE_XMLNode *pNode, FX_INT32 index = -1);
+ virtual void RemoveChildNode(CFDE_XMLNode *pNode);
+ virtual void DeleteChildren();
+ virtual CFDE_XMLNode* GetNodeItem(IFDE_XMLNode::NodeItem eItem) const;
+ virtual FX_INT32 GetNodeLevel() const;
+ virtual FX_BOOL InsertNodeItem(IFDE_XMLNode::NodeItem eItem, CFDE_XMLNode *pNode);
+ virtual CFDE_XMLNode* RemoveNodeItem(IFDE_XMLNode::NodeItem eItem);
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void SaveXMLNode(IFX_Stream *pXMLStream);
+public:
+ ~CFDE_XMLNode();
+ void CloneChildren(CFDE_XMLNode* pClone);
+ CFDE_XMLNode *m_pParent;
+ CFDE_XMLNode *m_pChild;
+ CFDE_XMLNode *m_pPrior;
+ CFDE_XMLNode *m_pNext;
+};
+class CFDE_XMLInstruction : public CFDE_XMLNode
+{
+public:
+ CFDE_XMLInstruction(const CFX_WideString &wsTarget);
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_Instruction;
+ }
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void GetTargetName(CFX_WideString &wsTarget) const
+ {
+ wsTarget = m_wsTarget;
+ }
+ virtual FX_INT32 CountAttributes() const;
+ virtual FX_BOOL GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const;
+ virtual FX_BOOL HasAttribute(FX_LPCWSTR pwsAttriName) const;
+ virtual void GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue = NULL) const;
+ virtual void SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue);
+ virtual FX_INT32 GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue = 0) const;
+ virtual void SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue);
+ virtual FX_FLOAT GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue = 0) const;
+ virtual void SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue);
+ virtual void RemoveAttribute(FX_LPCWSTR pwsAttriName);
+ virtual FX_INT32 CountData() const;
+ virtual FX_BOOL GetData(FX_INT32 index, CFX_WideString &wsData) const;
+ virtual void AppendData(const CFX_WideString &wsData);
+ virtual void RemoveData(FX_INT32 index);
+public:
+ ~CFDE_XMLInstruction() {}
+ CFX_WideString m_wsTarget;
+ CFX_WideStringArray m_Attributes;
+ CFX_WideStringArray m_TargetData;
+};
+class CFDE_XMLElement : public CFDE_XMLNode
+{
+public:
+ CFDE_XMLElement(const CFX_WideString &wsTag);
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_Element;
+ }
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void GetTagName(CFX_WideString &wsTag) const;
+ virtual void GetLocalTagName(CFX_WideString &wsTag) const;
+ virtual void GetNamespacePrefix(CFX_WideString &wsPrefix) const;
+ virtual void GetNamespaceURI(CFX_WideString &wsNamespace) const;
+ virtual FX_INT32 CountAttributes() const;
+ virtual FX_BOOL GetAttribute(FX_INT32 index, CFX_WideString &wsAttriName, CFX_WideString &wsAttriValue) const;
+ virtual FX_BOOL HasAttribute(FX_LPCWSTR pwsAttriName) const;
+ virtual void GetString(FX_LPCWSTR pwsAttriName, CFX_WideString &wsAttriValue, FX_LPCWSTR pwsDefValue = NULL) const;
+ virtual void SetString(const CFX_WideString &wsAttriName, const CFX_WideString &wsAttriValue);
+ virtual FX_INT32 GetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iDefValue = 0) const;
+ virtual void SetInteger(FX_LPCWSTR pwsAttriName, FX_INT32 iAttriValue);
+ virtual FX_FLOAT GetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fDefValue = 0) const;
+ virtual void SetFloat(FX_LPCWSTR pwsAttriName, FX_FLOAT fAttriValue);
+ virtual void RemoveAttribute(FX_LPCWSTR pwsAttriName);
+ virtual void GetTextData(CFX_WideString &wsText) const;
+ virtual void SetTextData(const CFX_WideString &wsText);
+public:
+ ~CFDE_XMLElement();
+ CFX_WideString m_wsTag;
+ CFX_WideStringArray m_Attributes;
+};
+class CFDE_XMLText : public CFDE_XMLNode
+{
+public:
+ CFDE_XMLText(const CFX_WideString &wsText);
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_Text;
+ }
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void GetText(CFX_WideString &wsText) const
+ {
+ wsText = m_wsText;
+ }
+ virtual void SetText(const CFX_WideString &wsText)
+ {
+ m_wsText = wsText;
+ }
+public:
+ ~CFDE_XMLText() {}
+ CFX_WideString m_wsText;
+};
+class CFDE_XMLDeclaration : public CFDE_XMLNode
+{
+public:
+ CFDE_XMLDeclaration() : CFDE_XMLNode() { }
+};
+class CFDE_XMLCharData : public CFDE_XMLDeclaration
+{
+public:
+ CFDE_XMLCharData(const CFX_WideString &wsCData);
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FDE_XMLNODETYPE GetType() const
+ {
+ return FDE_XMLNODE_CharData;
+ }
+ virtual CFDE_XMLNode* Clone(FX_BOOL bRecursive);
+ virtual void GetCharData(CFX_WideString &wsCharData) const
+ {
+ wsCharData = m_wsCharData;
+ }
+ virtual void SetCharData(const CFX_WideString &wsCData)
+ {
+ m_wsCharData = wsCData;
+ }
+
+public:
+ ~CFDE_XMLCharData() {}
+
+ CFX_WideString m_wsCharData;
+};
+class CFDE_XMLDoc : public CFX_Target
+{
+public:
+ CFDE_XMLDoc();
+ ~CFDE_XMLDoc();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_BOOL LoadXML(IFX_Stream *pXMLStream, FX_INT32 iXMLPlaneSize = 8192, FX_INT32 iTextDataSize = 256, FDE_LPXMLREADERHANDLER pHandler = NULL);
+ virtual FX_BOOL LoadXML(IFDE_XMLParser *pXMLParser);
+ virtual FX_INT32 DoLoad(IFX_Pause *pPause = NULL);
+ virtual void CloseXML();
+ virtual CFDE_XMLNode* GetRoot() const
+ {
+ return m_pRoot;
+ }
+ virtual void SaveXML(IFX_Stream *pXMLStream = NULL, FX_BOOL bSaveBOM = TRUE);
+ virtual void SaveXMLNode(IFX_Stream *pXMLStream, IFDE_XMLNode *pNode);
+protected:
+ IFX_Stream *m_pStream;
+ FX_INT32 m_iStatus;
+ CFDE_XMLNode *m_pRoot;
+ IFDE_XMLSyntaxParser *m_pSyntaxParser;
+ IFDE_XMLParser *m_pXMLParser;
+ void Reset(FX_BOOL bInitRoot);
+ void ReleaseParser();
+};
+typedef CFX_StackTemplate<CFDE_XMLNode*> CFDE_XMLDOMNodeStack;
+class CFDE_XMLDOMParser : public IFDE_XMLParser, public CFX_Target
+{
+public:
+ CFDE_XMLDOMParser(CFDE_XMLNode *pRoot, IFDE_XMLSyntaxParser *pParser);
+ ~CFDE_XMLDOMParser();
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 DoParser(IFX_Pause *pPause);
+private:
+ CFDE_XMLNode *m_pRoot;
+ IFDE_XMLSyntaxParser *m_pParser;
+ CFDE_XMLNode *m_pParent;
+ CFDE_XMLNode *m_pChild;
+ CFDE_XMLDOMNodeStack m_NodeStack;
+ CFX_WideString m_ws1;
+ CFX_WideString m_ws2;
+};
+class CFDE_XMLTAG : public CFX_Target
+{
+public:
+ CFDE_XMLTAG() : eType(FDE_XMLNODE_Unknown) {}
+ CFDE_XMLTAG(const CFDE_XMLTAG &src) : wsTagName(src.wsTagName), eType(src.eType) {}
+ CFX_WideString wsTagName;
+ FDE_XMLNODETYPE eType;
+};
+typedef CFX_ObjectStackTemplate<CFDE_XMLTAG> CFDE_XMLTagStack;
+class CFDE_XMLSAXParser : public IFDE_XMLParser, public CFX_Target
+{
+public:
+ CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, IFDE_XMLSyntaxParser *pParser);
+ ~CFDE_XMLSAXParser();
+
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual FX_INT32 DoParser(IFX_Pause *pPause);
+private:
+ void Push(const CFDE_XMLTAG &xmlTag);
+ void Pop();
+ FDE_LPXMLREADERHANDLER m_pHandler;
+ IFDE_XMLSyntaxParser *m_pParser;
+ CFDE_XMLTagStack m_TagStack;
+ CFDE_XMLTAG *m_pTagTop;
+ CFX_WideString m_ws1;
+ CFX_WideString m_ws2;
+};
+#ifdef _FDE_BLOCK_BUFFER
+class CFDE_BlockBuffer : public CFX_Target
+{
+public:
+ CFDE_BlockBuffer(FX_INT32 iAllocStep = 1024 * 1024);
+ ~CFDE_BlockBuffer();
+
+ FX_BOOL InitBuffer(FX_INT32 iBufferSize = 1024 * 1024);
+ FX_BOOL IsInitialized()
+ {
+ return m_iBufferSize / m_iAllocStep >= 1;
+ }
+ void ReleaseBuffer()
+ {
+ FDE_Delete this;
+ }
+ FX_LPWSTR GetAvailableBlock(FX_INT32& iIndexInBlock);
+ inline FX_INT32 GetAllocStep() const
+ {
+ return m_iAllocStep;
+ }
+ inline FX_INT32& GetDataLengthRef()
+ {
+ return m_iDataLength;
+ }
+ inline void Reset(FX_BOOL bReserveData = TRUE)
+ {
+ if (!bReserveData) {
+ m_iStartPosition = 0;
+ }
+ m_iDataLength = 0;
+ }
+ void SetTextChar(FX_INT32 iIndex, FX_WCHAR ch);
+ FX_INT32 DeleteTextChars(FX_INT32 iCount, FX_BOOL bDirection = TRUE);
+ void GetTextData(CFX_WideString& wsTextData, FX_INT32 iStart = 0, FX_INT32 iLength = -1) const;
+
+protected:
+ inline void TextDataIndex2BufIndex(const FX_INT32 iIndex, FX_INT32& iBlockIndex, FX_INT32& iInnerIndex) const;
+ void ClearBuffer();
+ CFX_PtrArray m_BlockArray;
+ FX_INT32 m_iDataLength;
+ FX_INT32 m_iBufferSize;
+ FX_INT32 m_iAllocStep;
+ FX_INT32 m_iStartPosition;
+};
+#endif
+#define FDE_XMLSYNTAXMODE_Text 0
+#define FDE_XMLSYNTAXMODE_Node 1
+#define FDE_XMLSYNTAXMODE_Target 2
+#define FDE_XMLSYNTAXMODE_Tag 3
+#define FDE_XMLSYNTAXMODE_AttriName 4
+#define FDE_XMLSYNTAXMODE_AttriEqualSign 5
+#define FDE_XMLSYNTAXMODE_AttriQuotation 6
+#define FDE_XMLSYNTAXMODE_AttriValue 7
+#define FDE_XMLSYNTAXMODE_Entity 8
+#define FDE_XMLSYNTAXMODE_EntityDecimal 9
+#define FDE_XMLSYNTAXMODE_EntityHex 10
+#define FDE_XMLSYNTAXMODE_CloseInstruction 11
+#define FDE_XMLSYNTAXMODE_BreakElement 12
+#define FDE_XMLSYNTAXMODE_CloseElement 13
+#define FDE_XMLSYNTAXMODE_SkipDeclNode 14
+#define FDE_XMLSYNTAXMODE_DeclCharData 15
+#define FDE_XMLSYNTAXMODE_SkipComment 16
+#define FDE_XMLSYNTAXMODE_SkipCommentOrDecl 17
+#define FDE_XMLSYNTAXMODE_TargetData 18
+class CFDE_XMLSyntaxParser : public IFDE_XMLSyntaxParser, public CFX_Target
+{
+public:
+ CFDE_XMLSyntaxParser();
+ ~CFDE_XMLSyntaxParser();
+ virtual void Release()
+ {
+ FDE_Delete this;
+ }
+ virtual void Init(IFX_Stream *pStream, FX_INT32 iXMLPlaneSize, FX_INT32 iTextDataSize = 256);
+ virtual FX_DWORD DoSyntaxParse();
+ virtual FX_INT32 GetStatus() const;
+ virtual FX_INT32 GetCurrentPos() const
+ {
+ return m_iParsedChars + (m_pStart - m_pBuffer);
+ }
+ virtual FX_FILESIZE GetCurrentBinaryPos() const;
+ virtual FX_INT32 GetCurrentNodeNumber() const
+ {
+ return m_iCurrentNodeNum;
+ }
+ virtual FX_INT32 GetLastNodeNumber() const
+ {
+ return m_iLastNodeNum;
+ }
+#ifdef _FDE_BLOCK_BUFFER
+ virtual void GetTargetName(CFX_WideString &wsTarget) const
+ {
+ m_BlockBuffer.GetTextData(wsTarget, 0, m_iTextDataLength);
+ }
+ virtual void GetTagName(CFX_WideString &wsTag) const
+ {
+ m_BlockBuffer.GetTextData(wsTag, 0, m_iTextDataLength);
+ }
+ virtual void GetAttributeName(CFX_WideString &wsAttriName) const
+ {
+ m_BlockBuffer.GetTextData(wsAttriName, 0, m_iTextDataLength);
+ }
+ virtual void GetAttributeValue(CFX_WideString &wsAttriValue) const
+ {
+ m_BlockBuffer.GetTextData(wsAttriValue, 0, m_iTextDataLength);
+ }
+ virtual void GetTextData(CFX_WideString &wsText) const
+ {
+ m_BlockBuffer.GetTextData(wsText, 0, m_iTextDataLength);
+ }
+ virtual void GetTargetData(CFX_WideString &wsData) const
+ {
+ m_BlockBuffer.GetTextData(wsData, 0, m_iTextDataLength);
+ }
+#else
+ virtual void GetTargetName(CFX_WideString &wsTarget) const
+ {
+ GetData(wsTarget);
+ }
+ virtual void GetTagName(CFX_WideString &wsTag) const
+ {
+ GetData(wsTag);
+ }
+ virtual void GetAttributeName(CFX_WideString &wsAttriName) const
+ {
+ GetData(wsAttriName);
+ }
+ virtual void GetAttributeValue(CFX_WideString &wsAttriValue) const
+ {
+ GetData(wsAttriValue);
+ }
+ virtual void GetTextData(CFX_WideString &wsText) const
+ {
+ GetData(wsText);
+ }
+ virtual void GetTargetData(CFX_WideString &wsData) const
+ {
+ GetData(wsData);
+ }
+#endif
+protected:
+ IFX_Stream *m_pStream;
+ FX_INT32 m_iXMLPlaneSize;
+ FX_INT32 m_iCurrentPos;
+ FX_INT32 m_iCurrentNodeNum;
+ FX_INT32 m_iLastNodeNum;
+ FX_INT32 m_iParsedChars;
+ FX_INT32 m_iParsedBytes;
+ FX_LPWSTR m_pBuffer;
+ FX_INT32 m_iBufferChars;
+ FX_BOOL m_bEOS;
+ FX_LPWSTR m_pStart;
+ FX_LPWSTR m_pEnd;
+ FDE_XMLNODE m_CurNode;
+ CFDE_XMLNodeStack m_XMLNodeStack;
+#ifdef _FDE_BLOCK_BUFFER
+ CFDE_BlockBuffer m_BlockBuffer;
+ FX_INT32 m_iAllocStep;
+ FX_INT32& m_iDataLength;
+ FX_LPWSTR m_pCurrentBlock;
+ FX_INT32 m_iIndexInBlock;
+#else
+ FX_INT32 m_iTextDataSize;
+ FX_LPWSTR m_pwsTextData;
+ FX_INT32 m_iDataPos;
+#endif
+ FX_INT32 m_iTextDataLength;
+ FX_DWORD m_dwStatus;
+ FX_DWORD m_dwMode;
+ FX_WCHAR m_wQuotationMark;
+ FX_INT32 m_iEntityStart;
+ CFX_DWordStack m_SkipStack;
+ FX_WCHAR m_SkipChar;
+ inline void ParseTextChar(FX_WCHAR ch);
+#ifndef _FDE_BLOCK_BUFFER
+ void ReallocTextDataBuffer();
+ void GetData(CFX_WideString &wsData) const;
+#endif
+};
+#endif