summaryrefslogtreecommitdiff
path: root/core/src/fxge
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fxge')
-rw-r--r--core/src/fxge/Microsoft SDK/include/DWrite.h10012
-rw-r--r--core/src/fxge/Microsoft SDK/include/Dcommon.h130
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlus.h312
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusBase.h80
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusBitmap.h2008
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusBrush.h1902
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusCachedBitmap.h142
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusColor.h418
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusColorMatrix.h126
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusEnums.h2504
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusFlat.h5480
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusFont.h598
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusFontCollection.h298
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusFontFamily.h542
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusGpStubs.h214
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusGraphics.h5452
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusHeaders.h1586
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusImageCodec.h146
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusImaging.h1080
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusLineCaps.h506
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusMatrix.h618
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusMem.h98
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusMetaFile.h748
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusMetaHeader.h426
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusPath.h3372
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusPen.h1038
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusPixelFormats.h402
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusRegion.h996
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusStringFormat.h762
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusTypes.h1652
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiPlusimageAttributes.h794
-rw-r--r--core/src/fxge/Microsoft SDK/include/GdiplusInit.h208
-rw-r--r--core/src/fxge/Microsoft SDK/include/sal.h1458
-rw-r--r--core/src/fxge/Microsoft SDK/include/specstrings.h1956
-rw-r--r--core/src/fxge/apple/apple_int.h492
-rw-r--r--core/src/fxge/apple/fx_apple_platform.cpp346
-rw-r--r--core/src/fxge/apple/fx_mac_imp.cpp234
-rw-r--r--core/src/fxge/apple/fx_quartz_device.cpp2276
-rw-r--r--core/src/fxge/dib/dib_int.h176
-rw-r--r--core/src/fxge/dib/fx_dib_composite.cpp9204
-rw-r--r--core/src/fxge/dib/fx_dib_convert.cpp2180
-rw-r--r--core/src/fxge/dib/fx_dib_engine.cpp1734
-rw-r--r--core/src/fxge/dib/fx_dib_main.cpp3468
-rw-r--r--core/src/fxge/dib/fx_dib_transform.cpp1594
-rw-r--r--core/src/fxge/ge/fx_ge.cpp158
-rw-r--r--core/src/fxge/ge/fx_ge_device.cpp810
-rw-r--r--core/src/fxge/ge/fx_ge_font.cpp916
-rw-r--r--core/src/fxge/ge/fx_ge_fontmap.cpp3116
-rw-r--r--core/src/fxge/ge/fx_ge_linux.cpp518
-rw-r--r--core/src/fxge/ge/fx_ge_path.cpp1308
-rw-r--r--core/src/fxge/ge/fx_ge_ps.cpp1314
-rw-r--r--core/src/fxge/ge/fx_ge_text.cpp3548
-rw-r--r--core/src/fxge/ge/text_int.h200
-rw-r--r--core/src/fxge/win32/dwrite_int.h118
-rw-r--r--core/src/fxge/win32/fx_win32_device.cpp2400
-rw-r--r--core/src/fxge/win32/fx_win32_dib.cpp620
-rw-r--r--core/src/fxge/win32/fx_win32_dwrite.cpp960
-rw-r--r--core/src/fxge/win32/fx_win32_gdipext.cpp2572
-rw-r--r--core/src/fxge/win32/fx_win32_print.cpp852
-rw-r--r--core/src/fxge/win32/win32_int.h476
60 files changed, 44827 insertions, 44827 deletions
diff --git a/core/src/fxge/Microsoft SDK/include/DWrite.h b/core/src/fxge/Microsoft SDK/include/DWrite.h
index 70f998a437..0374694f74 100644
--- a/core/src/fxge/Microsoft SDK/include/DWrite.h
+++ b/core/src/fxge/Microsoft SDK/include/DWrite.h
@@ -1,5006 +1,5006 @@
-//+--------------------------------------------------------------------------
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Abstract:
-// DirectX Typography Services public API definitions.
-//
-//----------------------------------------------------------------------------
-
-#ifndef DWRITE_H_INCLUDED
-#define DWRITE_H_INCLUDED
-
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#ifndef DWRITE_NO_WINDOWS_H
-
-#include "specstrings.h"
-#include "unknwn.h"
-
-#endif // DWRITE_NO_WINDOWS_H
-
-#include "dcommon.h"
-
-#if _FX_COMPILER_ == _FX_VC6_
-typedef signed char INT8, *PINT8;
-typedef signed short INT16, *PINT16;
-typedef signed int INT32, *PINT32;
-typedef signed __int64 INT64, *PINT64;
-typedef unsigned char UINT8, *PUINT8;
-typedef unsigned short UINT16, *PUINT16;
-typedef unsigned int UINT32, *PUINT32;
-typedef unsigned __int64 UINT64, *PUINT64;
-#endif
-
-#ifndef DWRITE_DECLARE_INTERFACE
-#define DWRITE_DECLARE_INTERFACE(iid) DECLSPEC_UUID(iid) DECLSPEC_NOVTABLE
-#endif
-
-#ifndef DWRITE_EXPORT
-#define DWRITE_EXPORT __declspec(dllimport) WINAPI
-#endif
-
-/// <summary>
-/// The type of a font represented by a single font file.
-/// Font formats that consist of multiple files, e.g. Type 1 .PFM and .PFB, have
-/// separate enum values for each of the file type.
-/// </summary>
-enum DWRITE_FONT_FILE_TYPE
-{
- /// <summary>
- /// Font type is not recognized by the DirectWrite font system.
- /// </summary>
- DWRITE_FONT_FILE_TYPE_UNKNOWN,
-
- /// <summary>
- /// OpenType font with CFF outlines.
- /// </summary>
- DWRITE_FONT_FILE_TYPE_CFF,
-
- /// <summary>
- /// OpenType font with TrueType outlines.
- /// </summary>
- DWRITE_FONT_FILE_TYPE_TRUETYPE,
-
- /// <summary>
- /// OpenType font that contains a TrueType collection.
- /// </summary>
- DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION,
-
- /// <summary>
- /// Type 1 PFM font.
- /// </summary>
- DWRITE_FONT_FILE_TYPE_TYPE1_PFM,
-
- /// <summary>
- /// Type 1 PFB font.
- /// </summary>
- DWRITE_FONT_FILE_TYPE_TYPE1_PFB,
-
- /// <summary>
- /// Vector .FON font.
- /// </summary>
- DWRITE_FONT_FILE_TYPE_VECTOR,
-
- /// <summary>
- /// Bitmap .FON font.
- /// </summary>
- DWRITE_FONT_FILE_TYPE_BITMAP
-};
-
-/// <summary>
-/// The file format of a complete font face.
-/// Font formats that consist of multiple files, e.g. Type 1 .PFM and .PFB, have
-/// a single enum entry.
-/// </summary>
-enum DWRITE_FONT_FACE_TYPE
-{
- /// <summary>
- /// OpenType font face with CFF outlines.
- /// </summary>
- DWRITE_FONT_FACE_TYPE_CFF,
-
- /// <summary>
- /// OpenType font face with TrueType outlines.
- /// </summary>
- DWRITE_FONT_FACE_TYPE_TRUETYPE,
-
- /// <summary>
- /// OpenType font face that is a part of a TrueType collection.
- /// </summary>
- DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION,
-
- /// <summary>
- /// A Type 1 font face.
- /// </summary>
- DWRITE_FONT_FACE_TYPE_TYPE1,
-
- /// <summary>
- /// A vector .FON format font face.
- /// </summary>
- DWRITE_FONT_FACE_TYPE_VECTOR,
-
- /// <summary>
- /// A bitmap .FON format font face.
- /// </summary>
- DWRITE_FONT_FACE_TYPE_BITMAP,
-
- /// <summary>
- /// Font face type is not recognized by the DirectWrite font system.
- /// </summary>
- DWRITE_FONT_FACE_TYPE_UNKNOWN
-};
-
-/// <summary>
-/// Specifies algorithmic style simulations to be applied to the font face.
-/// Bold and oblique simulations can be combined via bitwise OR operation.
-/// </summary>
-enum DWRITE_FONT_SIMULATIONS
-{
- /// <summary>
- /// No simulations are performed.
- /// </summary>
- DWRITE_FONT_SIMULATIONS_NONE = 0x0000,
-
- /// <summary>
- /// Algorithmic emboldening is performed.
- /// </summary>
- DWRITE_FONT_SIMULATIONS_BOLD = 0x0001,
-
- /// <summary>
- /// Algorithmic italicization is performed.
- /// </summary>
- DWRITE_FONT_SIMULATIONS_OBLIQUE = 0x0002
-};
-
-#ifdef DEFINE_ENUM_FLAG_OPERATORS
-DEFINE_ENUM_FLAG_OPERATORS(DWRITE_FONT_SIMULATIONS);
-#endif
-
-/// <summary>
-/// The font weight enumeration describes common values for degree of blackness or thickness of strokes of characters in a font.
-/// Font weight values less than 1 or greater than 999 are considered to be invalid, and they are rejected by font API functions.
-/// </summary>
-enum DWRITE_FONT_WEIGHT
-{
- /// <summary>
- /// Predefined font weight : Thin (100).
- /// </summary>
- DWRITE_FONT_WEIGHT_THIN = 100,
-
- /// <summary>
- /// Predefined font weight : Extra-light (200).
- /// </summary>
- DWRITE_FONT_WEIGHT_EXTRA_LIGHT = 200,
-
- /// <summary>
- /// Predefined font weight : Ultra-light (200).
- /// </summary>
- DWRITE_FONT_WEIGHT_ULTRA_LIGHT = 200,
-
- /// <summary>
- /// Predefined font weight : Light (300).
- /// </summary>
- DWRITE_FONT_WEIGHT_LIGHT = 300,
-
- /// <summary>
- /// Predefined font weight : Normal (400).
- /// </summary>
- DWRITE_FONT_WEIGHT_NORMAL = 400,
-
- /// <summary>
- /// Predefined font weight : Regular (400).
- /// </summary>
- DWRITE_FONT_WEIGHT_REGULAR = 400,
-
- /// <summary>
- /// Predefined font weight : Medium (500).
- /// </summary>
- DWRITE_FONT_WEIGHT_MEDIUM = 500,
-
- /// <summary>
- /// Predefined font weight : Demi-bold (600).
- /// </summary>
- DWRITE_FONT_WEIGHT_DEMI_BOLD = 600,
-
- /// <summary>
- /// Predefined font weight : Semi-bold (600).
- /// </summary>
- DWRITE_FONT_WEIGHT_SEMI_BOLD = 600,
-
- /// <summary>
- /// Predefined font weight : Bold (700).
- /// </summary>
- DWRITE_FONT_WEIGHT_BOLD = 700,
-
- /// <summary>
- /// Predefined font weight : Extra-bold (800).
- /// </summary>
- DWRITE_FONT_WEIGHT_EXTRA_BOLD = 800,
-
- /// <summary>
- /// Predefined font weight : Ultra-bold (800).
- /// </summary>
- DWRITE_FONT_WEIGHT_ULTRA_BOLD = 800,
-
- /// <summary>
- /// Predefined font weight : Black (900).
- /// </summary>
- DWRITE_FONT_WEIGHT_BLACK = 900,
-
- /// <summary>
- /// Predefined font weight : Heavy (900).
- /// </summary>
- DWRITE_FONT_WEIGHT_HEAVY = 900,
-
- /// <summary>
- /// Predefined font weight : Extra-black (950).
- /// </summary>
- DWRITE_FONT_WEIGHT_EXTRA_BLACK = 950,
-
- /// <summary>
- /// Predefined font weight : Ultra-black (950).
- /// </summary>
- DWRITE_FONT_WEIGHT_ULTRA_BLACK = 950
-};
-
-/// <summary>
-/// The font stretch enumeration describes relative change from the normal aspect ratio
-/// as specified by a font designer for the glyphs in a font.
-/// Values less than 1 or greater than 9 are considered to be invalid, and they are rejected by font API functions.
-/// </summary>
-enum DWRITE_FONT_STRETCH
-{
- /// <summary>
- /// Predefined font stretch : Not known (0).
- /// </summary>
- DWRITE_FONT_STRETCH_UNDEFINED = 0,
-
- /// <summary>
- /// Predefined font stretch : Ultra-condensed (1).
- /// </summary>
- DWRITE_FONT_STRETCH_ULTRA_CONDENSED = 1,
-
- /// <summary>
- /// Predefined font stretch : Extra-condensed (2).
- /// </summary>
- DWRITE_FONT_STRETCH_EXTRA_CONDENSED = 2,
-
- /// <summary>
- /// Predefined font stretch : Condensed (3).
- /// </summary>
- DWRITE_FONT_STRETCH_CONDENSED = 3,
-
- /// <summary>
- /// Predefined font stretch : Semi-condensed (4).
- /// </summary>
- DWRITE_FONT_STRETCH_SEMI_CONDENSED = 4,
-
- /// <summary>
- /// Predefined font stretch : Normal (5).
- /// </summary>
- DWRITE_FONT_STRETCH_NORMAL = 5,
-
- /// <summary>
- /// Predefined font stretch : Medium (5).
- /// </summary>
- DWRITE_FONT_STRETCH_MEDIUM = 5,
-
- /// <summary>
- /// Predefined font stretch : Semi-expanded (6).
- /// </summary>
- DWRITE_FONT_STRETCH_SEMI_EXPANDED = 6,
-
- /// <summary>
- /// Predefined font stretch : Expanded (7).
- /// </summary>
- DWRITE_FONT_STRETCH_EXPANDED = 7,
-
- /// <summary>
- /// Predefined font stretch : Extra-expanded (8).
- /// </summary>
- DWRITE_FONT_STRETCH_EXTRA_EXPANDED = 8,
-
- /// <summary>
- /// Predefined font stretch : Ultra-expanded (9).
- /// </summary>
- DWRITE_FONT_STRETCH_ULTRA_EXPANDED = 9
-};
-
-/// <summary>
-/// The font style enumeration describes the slope style of a font face, such as Normal, Italic or Oblique.
-/// Values other than the ones defined in the enumeration are considered to be invalid, and they are rejected by font API functions.
-/// </summary>
-enum DWRITE_FONT_STYLE
-{
- /// <summary>
- /// Font slope style : Normal.
- /// </summary>
- DWRITE_FONT_STYLE_NORMAL,
-
- /// <summary>
- /// Font slope style : Oblique.
- /// </summary>
- DWRITE_FONT_STYLE_OBLIQUE,
-
- /// <summary>
- /// Font slope style : Italic.
- /// </summary>
- DWRITE_FONT_STYLE_ITALIC
-
-};
-
-/// <summary>
-/// The informational string enumeration identifies a string in a font.
-/// </summary>
-enum DWRITE_INFORMATIONAL_STRING_ID
-{
- /// <summary>
- /// Unspecified name ID.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_NONE,
-
- /// <summary>
- /// Copyright notice provided by the font.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE,
-
- /// <summary>
- /// String containing a version number.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_VERSION_STRINGS,
-
- /// <summary>
- /// Trademark information provided by the font.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_TRADEMARK,
-
- /// <summary>
- /// Name of the font manufacturer.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
-
- /// <summary>
- /// Name of the font designer.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_DESIGNER,
-
- /// <summary>
- /// URL of font designer (with protocol, e.g., http://, ftp://).
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_DESIGNER_URL,
-
- /// <summary>
- /// Description of the font. Can contain revision information, usage recommendations, history, features, etc.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_DESCRIPTION,
-
- /// <summary>
- /// URL of font vendor (with protocol, e.g., http://, ftp://). If a unique serial number is embedded in the URL, it can be used to register the font.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_FONT_VENDOR_URL,
-
- /// <summary>
- /// Description of how the font may be legally used, or different example scenarios for licensed use. This field should be written in plain language, not legalese.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_LICENSE_DESCRIPTION,
-
- /// <summary>
- /// URL where additional licensing information can be found.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_LICENSE_INFO_URL,
-
- /// <summary>
- /// GDI-compatible family name. Because GDI allows a maximum of four fonts per family, fonts in the same family may have different GDI-compatible family names
- /// (e.g., "Arial", "Arial Narrow", "Arial Black").
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES,
-
- /// <summary>
- /// GDI-compatible subfamily name.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES,
-
- /// <summary>
- /// Family name preferred by the designer. This enables font designers to group more than four fonts in a single family without losing compatibility with
- /// GDI. This name is typically only present if it differs from the GDI-compatible family name.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_PREFERRED_FAMILY_NAMES,
-
- /// <summary>
- /// Subfamily name preferred by the designer. This name is typically only present if it differs from the GDI-compatible subfamily name.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_PREFERRED_SUBFAMILY_NAMES,
-
- /// <summary>
- /// Sample text. This can be the font name or any other text that the designer thinks is the best example to display the font in.
- /// </summary>
- DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT
-};
-
-
-/// <summary>
-/// The DWRITE_FONT_METRICS structure specifies the metrics of a font face that
-/// are applicable to all glyphs within the font face.
-/// </summary>
-struct DWRITE_FONT_METRICS
-{
- /// <summary>
- /// The number of font design units per em unit.
- /// Font files use their own coordinate system of font design units.
- /// A font design unit is the smallest measurable unit in the em square,
- /// an imaginary square that is used to size and align glyphs.
- /// The concept of em square is used as a reference scale factor when defining font size and device transformation semantics.
- /// The size of one em square is also commonly used to compute the paragraph identation value.
- /// </summary>
- UINT16 designUnitsPerEm;
-
- /// <summary>
- /// Ascent value of the font face in font design units.
- /// Ascent is the distance from the top of font character alignment box to English baseline.
- /// </summary>
- UINT16 ascent;
-
- /// <summary>
- /// Descent value of the font face in font design units.
- /// Descent is the distance from the bottom of font character alignment box to English baseline.
- /// </summary>
- UINT16 descent;
-
- /// <summary>
- /// Line gap in font design units.
- /// Recommended additional white space to add between lines to improve legibility. The recommended line spacing
- /// (baseline-to-baseline distance) is thus the sum of ascent, descent, and lineGap. The line gap is usually
- /// positive or zero but can be negative, in which case the recommended line spacing is less than the height
- /// of the character alignment box.
- /// </summary>
- INT16 lineGap;
-
- /// <summary>
- /// Cap height value of the font face in font design units.
- /// Cap height is the distance from English baseline to the top of a typical English capital.
- /// Capital "H" is often used as a reference character for the purpose of calculating the cap height value.
- /// </summary>
- UINT16 capHeight;
-
- /// <summary>
- /// x-height value of the font face in font design units.
- /// x-height is the distance from English baseline to the top of lowercase letter "x", or a similar lowercase character.
- /// </summary>
- UINT16 xHeight;
-
- /// <summary>
- /// The underline position value of the font face in font design units.
- /// Underline position is the position of underline relative to the English baseline.
- /// The value is usually made negative in order to place the underline below the baseline.
- /// </summary>
- INT16 underlinePosition;
-
- /// <summary>
- /// The suggested underline thickness value of the font face in font design units.
- /// </summary>
- UINT16 underlineThickness;
-
- /// <summary>
- /// The strikethrough position value of the font face in font design units.
- /// Strikethrough position is the position of strikethrough relative to the English baseline.
- /// The value is usually made positive in order to place the strikethrough above the baseline.
- /// </summary>
- INT16 strikethroughPosition;
-
- /// <summary>
- /// The suggested strikethrough thickness value of the font face in font design units.
- /// </summary>
- UINT16 strikethroughThickness;
-};
-
-/// <summary>
-/// The DWRITE_GLYPH_METRICS structure specifies the metrics of an individual glyph.
-/// The units depend on how the metrics are obtained.
-/// </summary>
-struct DWRITE_GLYPH_METRICS
-{
- /// <summary>
- /// Specifies the X offset from the glyph origin to the left edge of the black box.
- /// The glyph origin is the current horizontal writing position.
- /// A negative value means the black box extends to the left of the origin (often true for lowercase italic 'f').
- /// </summary>
- INT32 leftSideBearing;
-
- /// <summary>
- /// Specifies the X offset from the origin of the current glyph to the origin of the next glyph when writing horizontally.
- /// </summary>
- UINT32 advanceWidth;
-
- /// <summary>
- /// Specifies the X offset from the right edge of the black box to the origin of the next glyph when writing horizontally.
- /// The value is negative when the right edge of the black box overhangs the layout box.
- /// </summary>
- INT32 rightSideBearing;
-
- /// <summary>
- /// Specifies the vertical offset from the vertical origin to the top of the black box.
- /// Thus, a positive value adds whitespace whereas a negative value means the glyph overhangs the top of the layout box.
- /// </summary>
- INT32 topSideBearing;
-
- /// <summary>
- /// Specifies the Y offset from the vertical origin of the current glyph to the vertical origin of the next glyph when writing vertically.
- /// (Note that the term "origin" by itself denotes the horizontal origin. The vertical origin is different.
- /// Its Y coordinate is specified by verticalOriginY value,
- /// and its X coordinate is half the advanceWidth to the right of the horizontal origin).
- /// </summary>
- UINT32 advanceHeight;
-
- /// <summary>
- /// Specifies the vertical distance from the black box's bottom edge to the advance height.
- /// Positive when the bottom edge of the black box is within the layout box.
- /// Negative when the bottom edge of black box overhangs the layout box.
- /// </summary>
- INT32 bottomSideBearing;
-
- /// <summary>
- /// Specifies the Y coordinate of a glyph's vertical origin, in the font's design coordinate system.
- /// The y coordinate of a glyph's vertical origin is the sum of the glyph's top side bearing
- /// and the top (i.e. yMax) of the glyph's bounding box.
- /// </summary>
- INT32 verticalOriginY;
-};
-
-/// <summary>
-/// Optional adjustment to a glyph's position. An glyph offset changes the position of a glyph without affecting
-/// the pen position. Offsets are in logical, pre-transform units.
-/// </summary>
-struct DWRITE_GLYPH_OFFSET
-{
- /// <summary>
- /// Offset in the advance direction of the run. A positive advance offset moves the glyph to the right
- /// (in pre-transform coordinates) if the run is left-to-right or to the left if the run is right-to-left.
- /// </summary>
- FLOAT advanceOffset;
-
- /// <summary>
- /// Offset in the ascent direction, i.e., the direction ascenders point. A positive ascender offset moves
- /// the glyph up (in pre-transform coordinates).
- /// </summary>
- FLOAT ascenderOffset;
-};
-
-/// <summary>
-/// Specifies the type of DirectWrite factory object.
-/// DirectWrite factory contains internal state such as font loader registration and cached font data.
-/// In most cases it is recommended to use the shared factory object, because it allows multiple components
-/// that use DirectWrite to share internal DirectWrite state and reduce memory usage.
-/// However, there are cases when it is desirable to reduce the impact of a component,
-/// such as a plug-in from an untrusted source, on the rest of the process by sandboxing and isolating it
-/// from the rest of the process components. In such cases, it is recommended to use an isolated factory for the sandboxed
-/// component.
-/// </summary>
-enum DWRITE_FACTORY_TYPE
-{
- /// <summary>
- /// Shared factory allow for re-use of cached font data across multiple in process components.
- /// Such factories also take advantage of cross process font caching components for better performance.
- /// </summary>
- DWRITE_FACTORY_TYPE_SHARED,
-
- /// <summary>
- /// Objects created from the isolated factory do not interact with internal DirectWrite state from other components.
- /// </summary>
- DWRITE_FACTORY_TYPE_ISOLATED
-};
-
-// Creates an OpenType tag as a 32bit integer such that
-// the first character in the tag is the lowest byte,
-// (least significant on little endian architectures)
-// which can be used to compare with tags in the font file.
-// This macro is compatible with DWRITE_FONT_FEATURE_TAG.
-//
-// Example: DWRITE_MAKE_OPENTYPE_TAG('c','c','m','p')
-// Dword: 0x706D6363
-//
-#define DWRITE_MAKE_OPENTYPE_TAG(a,b,c,d) ( \
- (static_cast<UINT32>(static_cast<UINT8>(d)) << 24) | \
- (static_cast<UINT32>(static_cast<UINT8>(c)) << 16) | \
- (static_cast<UINT32>(static_cast<UINT8>(b)) << 8) | \
- static_cast<UINT32>(static_cast<UINT8>(a)))
-
-interface IDWriteFontFileStream;
-
-/// <summary>
-/// Font file loader interface handles loading font file resources of a particular type from a key.
-/// The font file loader interface is recommended to be implemented by a singleton object.
-/// IMPORTANT: font file loader implementations must not register themselves with DirectWrite factory
-/// inside their constructors and must not unregister themselves in their destructors, because
-/// registration and unregistraton operations increment and decrement the object reference count respectively.
-/// Instead, registration and unregistration of font file loaders with DirectWrite factory should be performed
-/// outside of the font file loader implementation as a separate step.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("727cad4e-d6af-4c9e-8a08-d695b11caa49") IDWriteFontFileLoader : public IUnknown
-{
- /// <summary>
- /// Creates a font file stream object that encapsulates an open file resource.
- /// The resource is closed when the last reference to fontFileStream is released.
- /// </summary>
- /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the font file resource
- /// within the scope of the font loader being used.</param>
- /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
- /// <param name="fontFileStream">Pointer to the newly created font file stream.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateStreamFromKey)(
- __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- __out IDWriteFontFileStream** fontFileStream
- ) PURE;
-};
-
-/// <summary>
-/// A built-in implementation of IDWriteFontFileLoader interface that operates on local font files
-/// and exposes local font file information from the font file reference key.
-/// Font file references created using CreateFontFileReference use this font file loader.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("b2d9f3ec-c9fe-4a11-a2ec-d86208f7c0a2") IDWriteLocalFontFileLoader : public IDWriteFontFileLoader
-{
- /// <summary>
- /// Obtains the length of the absolute file path from the font file reference key.
- /// </summary>
- /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the local font file
- /// within the scope of the font loader being used.</param>
- /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
- /// <param name="filePathLength">Length of the file path string not including the terminated NULL character.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFilePathLengthFromKey)(
- __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- __out UINT32* filePathLength
- ) PURE;
-
- /// <summary>
- /// Obtains the absolute font file path from the font file reference key.
- /// </summary>
- /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the local font file
- /// within the scope of the font loader being used.</param>
- /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
- /// <param name="filePath">Character array that receives the local file path.</param>
- /// <param name="filePathSize">Size of the filePath array in character count including the terminated NULL character.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFilePathFromKey)(
- __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- __out_ecount_z(filePathSize) WCHAR* filePath,
- UINT32 filePathSize
- ) PURE;
-
- /// <summary>
- /// Obtains the last write time of the file from the font file reference key.
- /// </summary>
- /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the local font file
- /// within the scope of the font loader being used.</param>
- /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
- /// <param name="lastWriteTime">Last modified time of the font file.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetLastWriteTimeFromKey)(
- __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- __out FILETIME* lastWriteTime
- ) PURE;
-};
-
-/// <summary>
-/// The interface for loading font file data.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("6d4865fe-0ab8-4d91-8f62-5dd6be34a3e0") IDWriteFontFileStream : public IUnknown
-{
- /// <summary>
- /// Reads a fragment from a file.
- /// </summary>
- /// <param name="fragmentStart">Receives the pointer to the start of the font file fragment.</param>
- /// <param name="fileOffset">Offset of the fragment from the beginning of the font file.</param>
- /// <param name="fragmentSize">Size of the fragment in bytes.</param>
- /// <param name="fragmentContext">The client defined context to be passed to the ReleaseFileFragment.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// IMPORTANT: ReadFileFragment() implementations must check whether the requested file fragment
- /// is within the file bounds. Otherwise, an error should be returned from ReadFileFragment.
- /// </remarks>
- STDMETHOD(ReadFileFragment)(
- __deref_out_bcount(fragmentSize) void const** fragmentStart,
- UINT64 fileOffset,
- UINT64 fragmentSize,
- __out void** fragmentContext
- ) PURE;
-
- /// <summary>
- /// Releases a fragment from a file.
- /// </summary>
- /// <param name="fragmentContext">The client defined context of a font fragment returned from ReadFileFragment.</param>
- STDMETHOD_(void, ReleaseFileFragment)(
- void* fragmentContext
- ) PURE;
-
- /// <summary>
- /// Obtains the total size of a file.
- /// </summary>
- /// <param name="fileSize">Receives the total size of the file.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// Implementing GetFileSize() for asynchronously loaded font files may require
- /// downloading the complete file contents, therefore this method should only be used for operations that
- /// either require complete font file to be loaded (e.g., copying a font file) or need to make
- /// decisions based on the value of the file size (e.g., validation against a persisted file size).
- /// </remarks>
- STDMETHOD(GetFileSize)(
- __out UINT64* fileSize
- ) PURE;
-
- /// <summary>
- /// Obtains the last modified time of the file. The last modified time is used by DirectWrite font selection algorithms
- /// to determine whether one font resource is more up to date than another one.
- /// </summary>
- /// <param name="lastWriteTime">Receives the last modifed time of the file in the format that represents
- /// the number of 100-nanosecond intervals since January 1, 1601 (UTC).</param>
- /// <returns>
- /// Standard HRESULT error code. For resources that don't have a concept of the last modified time, the implementation of
- /// GetLastWriteTime should return E_NOTIMPL.
- /// </returns>
- STDMETHOD(GetLastWriteTime)(
- __out UINT64* lastWriteTime
- ) PURE;
-};
-
-/// <summary>
-/// The interface that represents a reference to a font file.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("739d886a-cef5-47dc-8769-1a8b41bebbb0") IDWriteFontFile : public IUnknown
-{
- /// <summary>
- /// This method obtains the pointer to the reference key of a font file. The pointer is only valid until the object that refers to it is released.
- /// </summary>
- /// <param name="fontFileReferenceKey">Pointer to the font file reference key.
- /// IMPORTANT: The pointer value is valid until the font file reference object it is obtained from is released.</param>
- /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetReferenceKey)(
- __deref_out_bcount(*fontFileReferenceKeySize) void const** fontFileReferenceKey,
- __out UINT32* fontFileReferenceKeySize
- ) PURE;
-
- /// <summary>
- /// Obtains the file loader associated with a font file object.
- /// </summary>
- /// <param name="fontFileLoader">The font file loader associated with the font file object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetLoader)(
- __out IDWriteFontFileLoader** fontFileLoader
- ) PURE;
-
- /// <summary>
- /// Analyzes a file and returns whether it represents a font, and whether the font type is supported by the font system.
- /// </summary>
- /// <param name="isSupportedFontType">TRUE if the font type is supported by the font system, FALSE otherwise.</param>
- /// <param name="fontFileType">The type of the font file. Note that even if isSupportedFontType is FALSE,
- /// the fontFileType value may be different from DWRITE_FONT_FILE_TYPE_UNKNOWN.</param>
- /// <param name="fontFaceType">The type of the font face that can be constructed from the font file.
- /// Note that even if isSupportedFontType is FALSE, the fontFaceType value may be different from
- /// DWRITE_FONT_FACE_TYPE_UNKNOWN.</param>
- /// <param name="numberOfFaces">Number of font faces contained in the font file.</param>
- /// <returns>
- /// Standard HRESULT error code if there was a processing error during analysis.
- /// </returns>
- /// <remarks>
- /// IMPORTANT: certain font file types are recognized, but not supported by the font system.
- /// For example, the font system will recognize a file as a Type 1 font file,
- /// but will not be able to construct a font face object from it. In such situations, Analyze will set
- /// isSupportedFontType output parameter to FALSE.
- /// </remarks>
- STDMETHOD(Analyze)(
- __out BOOL* isSupportedFontType,
- __out DWRITE_FONT_FILE_TYPE* fontFileType,
- __out_opt DWRITE_FONT_FACE_TYPE* fontFaceType,
- __out UINT32* numberOfFaces
- ) PURE;
-};
-
-/// <summary>
-/// Represents the internal structure of a device pixel (i.e., the physical arrangement of red,
-/// green, and blue color components) that is assumed for purposes of rendering text.
-/// </summary>
-#ifndef DWRITE_PIXEL_GEOMETRY_DEFINED
-enum DWRITE_PIXEL_GEOMETRY
-{
- /// <summary>
- /// The red, green, and blue color components of each pixel are assumed to occupy the same point.
- /// </summary>
- DWRITE_PIXEL_GEOMETRY_FLAT,
-
- /// <summary>
- /// Each pixel comprises three vertical stripes, with red on the left, green in the center, and
- /// blue on the right. This is the most common pixel geometry for LCD monitors.
- /// </summary>
- DWRITE_PIXEL_GEOMETRY_RGB,
-
- /// <summary>
- /// Each pixel comprises three vertical stripes, with blue on the left, green in the center, and
- /// red on the right.
- /// </summary>
- DWRITE_PIXEL_GEOMETRY_BGR
-};
-#define DWRITE_PIXEL_GEOMETRY_DEFINED
-#endif
-
-/// <summary>
-/// Represents a method of rendering glyphs.
-/// </summary>
-enum DWRITE_RENDERING_MODE
-{
- /// <summary>
- /// Specifies that the rendering mode is determined automatically based on the font and size.
- /// </summary>
- DWRITE_RENDERING_MODE_DEFAULT,
-
- /// <summary>
- /// Specifies that no anti-aliasing is performed. Each pixel is either set to the foreground
- /// color of the text or retains the color of the background.
- /// </summary>
- DWRITE_RENDERING_MODE_ALIASED,
-
- /// <summary>
- /// Specifies ClearType rendering with the same metrics as aliased text. Glyphs can only
- /// be positioned on whole-pixel boundaries.
- /// </summary>
- DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC,
-
- /// <summary>
- /// Specifies ClearType rendering with the same metrics as text rendering using GDI using a font
- /// created with CLEARTYPE_NATURAL_QUALITY. Glyph metrics are closer to their ideal values than
- /// with aliased text, but glyphs are still positioned on whole-pixel boundaries.
- /// </summary>
- DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL,
-
- /// <summary>
- /// Specifies ClearType rendering with anti-aliasing in the horizontal dimension only. This is
- /// typically used with small to medium font sizes (up to 16 ppem).
- /// </summary>
- DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL,
-
- /// <summary>
- /// Specifies ClearType rendering with anti-aliasing in both horizontal and vertical dimensions.
- /// This is typically used at larger sizes to makes curves and diagonal lines look smoother, at
- /// the expense of some softness.
- /// </summary>
- DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
-
- /// <summary>
- /// Specifies that rendering should bypass the rasterizer and use the outlines directly. This is
- /// typically used at very large sizes.
- /// </summary>
- DWRITE_RENDERING_MODE_OUTLINE
-};
-
-/// <summary>
-/// The DWRITE_MATRIX structure specifies the graphics transform to be applied
-/// to rendered glyphs.
-/// </summary>
-struct DWRITE_MATRIX
-{
- /// <summary>
- /// Horizontal scaling / cosine of rotation
- /// </summary>
- FLOAT m11;
-
- /// <summary>
- /// Vertical shear / sine of rotation
- /// </summary>
- FLOAT m12;
-
- /// <summary>
- /// Horizontal shear / negative sine of rotation
- /// </summary>
- FLOAT m21;
-
- /// <summary>
- /// Vertical scaling / cosine of rotation
- /// </summary>
- FLOAT m22;
-
- /// <summary>
- /// Horizontal shift (always orthogonal regardless of rotation)
- /// </summary>
- FLOAT dx;
-
- /// <summary>
- /// Vertical shift (always orthogonal regardless of rotation)
- /// </summary>
- FLOAT dy;
-};
-
-/// <summary>
-/// The interface that represents text rendering settings for glyph rasterization and filtering.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("2f0da53a-2add-47cd-82ee-d9ec34688e75") IDWriteRenderingParams : public IUnknown
-{
- /// <summary>
- /// Gets the gamma value used for gamma correction. Valid values must be
- /// greater than zero and cannot exceed 256.
- /// </summary>
- STDMETHOD_(FLOAT, GetGamma)() PURE;
-
- /// <summary>
- /// Gets the amount of contrast enhancement. Valid values are greater than
- /// or equal to zero.
- /// </summary>
- STDMETHOD_(FLOAT, GetEnhancedContrast)() PURE;
-
- /// <summary>
- /// Gets the ClearType level. Valid values range from 0.0f (no ClearType)
- /// to 1.0f (full ClearType).
- /// </summary>
- STDMETHOD_(FLOAT, GetClearTypeLevel)() PURE;
-
- /// <summary>
- /// Gets the pixel geometry.
- /// </summary>
- STDMETHOD_(DWRITE_PIXEL_GEOMETRY, GetPixelGeometry)() PURE;
-
- /// <summary>
- /// Gets the rendering mode.
- /// </summary>
- STDMETHOD_(DWRITE_RENDERING_MODE, GetRenderingMode)() PURE;
-};
-
-// Forward declarations of D2D types
-interface ID2D1SimplifiedGeometrySink;
-
-typedef ID2D1SimplifiedGeometrySink IDWriteGeometrySink;
-
-/// <summary>
-/// The interface that represents an absolute reference to a font face.
-/// It contains font face type, appropriate file references and face identification data.
-/// Various font data such as metrics, names and glyph outlines is obtained from IDWriteFontFace.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("5f49804d-7024-4d43-bfa9-d25984f53849") IDWriteFontFace : public IUnknown
-{
- /// <summary>
- /// Obtains the file format type of a font face.
- /// </summary>
- STDMETHOD_(DWRITE_FONT_FACE_TYPE, GetType)() PURE;
-
- /// <summary>
- /// Obtains the font files representing a font face.
- /// </summary>
- /// <param name="numberOfFiles">The number of files representing the font face.</param>
- /// <param name="fontFiles">User provided array that stores pointers to font files representing the font face.
- /// This parameter can be NULL if the user is only interested in the number of files representing the font face.
- /// This API increments reference count of the font file pointers returned according to COM conventions, and the client
- /// should release them when finished.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFiles)(
- __inout UINT32* numberOfFiles,
- __out_ecount_opt(*numberOfFiles) IDWriteFontFile** fontFiles
- ) PURE;
-
- /// <summary>
- /// Obtains the zero-based index of the font face in its font file or files. If the font files contain a single face,
- /// the return value is zero.
- /// </summary>
- STDMETHOD_(UINT32, GetIndex)() PURE;
-
- /// <summary>
- /// Obtains the algorithmic style simulation flags of a font face.
- /// </summary>
- STDMETHOD_(DWRITE_FONT_SIMULATIONS, GetSimulations)() PURE;
-
- /// <summary>
- /// Determines whether the font is a symbol font.
- /// </summary>
- STDMETHOD_(BOOL, IsSymbolFont)() PURE;
-
- /// <summary>
- /// Obtains design units and common metrics for the font face.
- /// These metrics are applicable to all the glyphs within a fontface and are used by applications for layout calculations.
- /// </summary>
- /// <param name="fontFaceMetrics">Points to a DWRITE_FONT_METRICS structure to fill in.
- /// The metrics returned by this function are in font design units.</param>
- STDMETHOD_(void, GetMetrics)(
- __out DWRITE_FONT_METRICS* fontFaceMetrics
- ) PURE;
-
- /// <summary>
- /// Obtains the number of glyphs in the font face.
- /// </summary>
- STDMETHOD_(UINT16, GetGlyphCount)() PURE;
-
- /// <summary>
- /// Obtains ideal glyph metrics in font design units. Design glyphs metrics are used for glyph positioning.
- /// </summary>
- /// <param name="glyphIndices">An array of glyph indices to compute the metrics for.</param>
- /// <param name="glyphCount">The number of elements in the glyphIndices array.</param>
- /// <param name="glyphMetrics">Array of DWRITE_GLYPH_METRICS structures filled by this function.
- /// The metrics returned by this function are in font design units.</param>
- /// <param name="isSideways">Indicates whether the font is being used in a sideways run.
- /// This can affect the glyph metrics if the font has oblique simulation
- /// because sideways oblique simulation differs from non-sideways oblique simulation.</param>
- /// <returns>
- /// Standard HRESULT error code. If any of the input glyph indices are outside of the valid glyph index range
- /// for the current font face, E_INVALIDARG will be returned.
- /// </returns>
- STDMETHOD(GetDesignGlyphMetrics)(
- __in_ecount(glyphCount) UINT16 const* glyphIndices,
- UINT32 glyphCount,
- __out_ecount(glyphCount) DWRITE_GLYPH_METRICS* glyphMetrics,
- BOOL isSideways = FALSE
- ) PURE;
-
- /// <summary>
- /// Returns the nominal mapping of UCS4 Unicode code points to glyph indices as defined by the font 'CMAP' table.
- /// Note that this mapping is primarily provided for line layout engines built on top of the physical font API.
- /// Because of OpenType glyph substitution and line layout character substitution, the nominal conversion does not always correspond
- /// to how a Unicode string will map to glyph indices when rendering using a particular font face.
- /// Also, note that Unicode Variant Selectors provide for alternate mappings for character to glyph.
- /// This call will always return the default variant.
- /// </summary>
- /// <param name="codePoints">An array of USC4 code points to obtain nominal glyph indices from.</param>
- /// <param name="codePointCount">The number of elements in the codePoints array.</param>
- /// <param name="glyphIndices">Array of nominal glyph indices filled by this function.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetGlyphIndices)(
- __in_ecount(codePointCount) UINT32 const* codePoints,
- UINT32 codePointCount,
- __out_ecount(codePointCount) UINT16* glyphIndices
- ) PURE;
-
- /// <summary>
- /// Finds the specified OpenType font table if it exists and returns a pointer to it.
- /// The function accesses the underling font data via the IDWriteFontStream interface
- /// implemented by the font file loader.
- /// </summary>
- /// <param name="openTypeTableTag">Four character tag of table to find.
- /// Use the DWRITE_MAKE_OPENTYPE_TAG() macro to create it.
- /// Unlike GDI, it does not support the special TTCF and null tags to access the whole font.</param>
- /// <param name="tableData">
- /// Pointer to base of table in memory.
- /// The pointer is only valid so long as the FontFace used to get the font table still exists
- /// (not any other FontFace, even if it actually refers to the same physical font).
- /// </param>
- /// <param name="tableSize">Byte size of table.</param>
- /// <param name="tableContext">
- /// Opaque context which must be freed by calling ReleaseFontTable.
- /// The context actually comes from the lower level IDWriteFontFileStream,
- /// which may be implemented by the application or DWrite itself.
- /// It is possible for a NULL tableContext to be returned, especially if
- /// the implementation directly memory maps the whole file.
- /// Nevertheless, always release it later, and do not use it as a test for function success.
- /// The same table can be queried multiple times,
- /// but each returned context can be different, so release each separately.
- /// </param>
- /// <param name="exists">True if table exists.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// If a table can not be found, the function will not return an error, but the size will be 0, table NULL, and exists = FALSE.
- /// The context does not need to be freed if the table was not found.
- /// </returns>
- /// <remarks>
- /// The context for the same tag may be different for each call,
- /// so each one must be held and released separately.
- /// </remarks>
- STDMETHOD(TryGetFontTable)(
- __in UINT32 openTypeTableTag,
- __deref_out_bcount(*tableSize) const void** tableData,
- __out UINT32* tableSize,
- __out void** tableContext,
- __out BOOL* exists
- ) PURE;
-
- /// <summary>
- /// Releases the table obtained earlier from TryGetFontTable.
- /// </summary>
- /// <param name="tableContext">Opaque context from TryGetFontTable.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD_(void, ReleaseFontTable)(
- __in void* tableContext
- ) PURE;
-
- /// <summary>
- /// Computes the outline of a run of glyphs by calling back to the outline sink interface.
- /// </summary>
- /// <param name="emSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
- /// <param name="glyphIndices">Array of glyph indices.</param>
- /// <param name="glyphAdvances">Optional array of glyph advances in DIPs.</param>
- /// <param name="glyphOffsets">Optional array of glyph offsets.</param>
- /// <param name="glyphCount">Number of glyphs.</param>
- /// <param name="isSideways">If true, specifies that glyphs are rotated 90 degrees to the left and vertical metrics are used.
- /// A client can render a vertical run by specifying isSideways = true and rotating the resulting geometry 90 degrees to the
- /// right using a transform. The isSideways and isRightToLeft parameters cannot both be true.</param>
- /// <param name="isRightToLeft">If true, specifies that the advance direction is right to left. By default, the advance direction
- /// is left to right.</param>
- /// <param name="geometrySink">Interface the function calls back to draw each element of the geometry.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetGlyphRunOutline)(
- FLOAT emSize,
- __in_ecount(glyphCount) UINT16 const* glyphIndices,
- __in_ecount_opt(glyphCount) FLOAT const* glyphAdvances,
- __in_ecount_opt(glyphCount) DWRITE_GLYPH_OFFSET const* glyphOffsets,
- UINT32 glyphCount,
- BOOL isSideways,
- BOOL isRightToLeft,
- IDWriteGeometrySink* geometrySink
- ) PURE;
-
- /// <summary>
- /// Determines the recommended rendering mode for the font given the specified size and rendering parameters.
- /// </summary>
- /// <param name="emSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
- /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this
- /// value is 1.0f. If the DPI is 120, this value is 120.0f/96.</param>
- /// <param name="measuringMode">Specifies measuring method that will be used for glyphs in the font.
- /// Renderer implementations may choose different rendering modes for given measuring methods, but
- /// best results are seen when the corresponding modes match:
- /// DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL for DWRITE_MEASURING_MODE_NATURAL
- /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC for DWRITE_MEASURING_MODE_GDI_CLASSIC
- /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL for DWRITE_MEASURING_MODE_GDI_NATURAL
- /// </param>
- /// <param name="renderingParams">Rendering parameters object. This parameter is necessary in case the rendering parameters
- /// object overrides the rendering mode.</param>
- /// <param name="renderingMode">Receives the recommended rendering mode to use.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetRecommendedRenderingMode)(
- FLOAT emSize,
- FLOAT pixelsPerDip,
- DWRITE_MEASURING_MODE measuringMode,
- IDWriteRenderingParams* renderingParams,
- __out DWRITE_RENDERING_MODE* renderingMode
- ) PURE;
-
- /// <summary>
- /// Obtains design units and common metrics for the font face.
- /// These metrics are applicable to all the glyphs within a fontface and are used by applications for layout calculations.
- /// </summary>
- /// <param name="emSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
- /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this
- /// value is 1.0f. If the DPI is 120, this value is 120.0f/96.</param>
- /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
- /// scaling specified by the font size and pixelsPerDip.</param>
- /// <param name="fontFaceMetrics">Points to a DWRITE_FONT_METRICS structure to fill in.
- /// The metrics returned by this function are in font design units.</param>
- STDMETHOD(GetGdiCompatibleMetrics)(
- FLOAT emSize,
- FLOAT pixelsPerDip,
- __in_opt DWRITE_MATRIX const* transform,
- __out DWRITE_FONT_METRICS* fontFaceMetrics
- ) PURE;
-
-
- /// <summary>
- /// Obtains glyph metrics in font design units with the return values compatible with what GDI would produce.
- /// Glyphs metrics are used for positioning of individual glyphs.
- /// </summary>
- /// <param name="emSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
- /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this
- /// value is 1.0f. If the DPI is 120, this value is 120.0f/96.</param>
- /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
- /// scaling specified by the font size and pixelsPerDip.</param>
- /// <param name="useGdiNatural">
- /// When set to FALSE, the metrics are the same as the metrics of GDI aliased text.
- /// When set to TRUE, the metrics are the same as the metrics of text measured by GDI using a font
- /// created with CLEARTYPE_NATURAL_QUALITY.
- /// </param>
- /// <param name="glyphIndices">An array of glyph indices to compute the metrics for.</param>
- /// <param name="glyphCount">The number of elements in the glyphIndices array.</param>
- /// <param name="glyphMetrics">Array of DWRITE_GLYPH_METRICS structures filled by this function.
- /// The metrics returned by this function are in font design units.</param>
- /// <param name="isSideways">Indicates whether the font is being used in a sideways run.
- /// This can affect the glyph metrics if the font has oblique simulation
- /// because sideways oblique simulation differs from non-sideways oblique simulation.</param>
- /// <returns>
- /// Standard HRESULT error code. If any of the input glyph indices are outside of the valid glyph index range
- /// for the current font face, E_INVALIDARG will be returned.
- /// </returns>
- STDMETHOD(GetGdiCompatibleGlyphMetrics)(
- FLOAT emSize,
- FLOAT pixelsPerDip,
- __in_opt DWRITE_MATRIX const* transform,
- BOOL useGdiNatural,
- __in_ecount(glyphCount) UINT16 const* glyphIndices,
- UINT32 glyphCount,
- __out_ecount(glyphCount) DWRITE_GLYPH_METRICS* glyphMetrics,
- BOOL isSideways = FALSE
- ) PURE;
-};
-
-interface IDWriteFactory;
-interface IDWriteFontFileEnumerator;
-
-/// <summary>
-/// The font collection loader interface is used to construct a collection of fonts given a particular type of key.
-/// The font collection loader interface is recommended to be implemented by a singleton object.
-/// IMPORTANT: font collection loader implementations must not register themselves with a DirectWrite factory
-/// inside their constructors and must not unregister themselves in their destructors, because
-/// registration and unregistraton operations increment and decrement the object reference count respectively.
-/// Instead, registration and unregistration of font file loaders with DirectWrite factory should be performed
-/// outside of the font file loader implementation as a separate step.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("cca920e4-52f0-492b-bfa8-29c72ee0a468") IDWriteFontCollectionLoader : public IUnknown
-{
- /// <summary>
- /// Creates a font file enumerator object that encapsulates a collection of font files.
- /// The font system calls back to this interface to create a font collection.
- /// </summary>
- /// <param name="factory">Factory associated with the loader.</param>
- /// <param name="collectionKey">Font collection key that uniquely identifies the collection of font files within
- /// the scope of the font collection loader being used.</param>
- /// <param name="collectionKeySize">Size of the font collection key in bytes.</param>
- /// <param name="fontFileEnumerator">Pointer to the newly created font file enumerator.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateEnumeratorFromKey)(
- IDWriteFactory* factory,
- __in_bcount(collectionKeySize) void const* collectionKey,
- UINT32 collectionKeySize,
- __out IDWriteFontFileEnumerator** fontFileEnumerator
- ) PURE;
-};
-
-/// <summary>
-/// The font file enumerator interface encapsulates a collection of font files. The font system uses this interface
-/// to enumerate font files when building a font collection.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("72755049-5ff7-435d-8348-4be97cfa6c7c") IDWriteFontFileEnumerator : public IUnknown
-{
- /// <summary>
- /// Advances to the next font file in the collection. When it is first created, the enumerator is positioned
- /// before the first element of the collection and the first call to MoveNext advances to the first file.
- /// </summary>
- /// <param name="hasCurrentFile">Receives the value TRUE if the enumerator advances to a file, or FALSE if
- /// the enumerator advanced past the last file in the collection.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(MoveNext)(
- __out BOOL* hasCurrentFile
- ) PURE;
-
- /// <summary>
- /// Gets a reference to the current font file.
- /// </summary>
- /// <param name="fontFile">Pointer to the newly created font file object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetCurrentFontFile)(
- __out IDWriteFontFile** fontFile
- ) PURE;
-};
-
-/// <summary>
-/// Represents a collection of strings indexed by locale name.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("08256209-099a-4b34-b86d-c22b110e7771") IDWriteLocalizedStrings : public IUnknown
-{
- /// <summary>
- /// Gets the number of language/string pairs.
- /// </summary>
- STDMETHOD_(UINT32, GetCount)() PURE;
-
- /// <summary>
- /// Gets the index of the item with the specified locale name.
- /// </summary>
- /// <param name="localeName">Locale name to look for.</param>
- /// <param name="index">Receives the zero-based index of the locale name/string pair.</param>
- /// <param name="exists">Receives TRUE if the locale name exists or FALSE if not.</param>
- /// <returns>
- /// Standard HRESULT error code. If the specified locale name does not exist, the return value is S_OK,
- /// but *index is UINT_MAX and *exists is FALSE.
- /// </returns>
- STDMETHOD(FindLocaleName)(
- __in_z WCHAR const* localeName,
- __out UINT32* index,
- __out BOOL* exists
- ) PURE;
-
- /// <summary>
- /// Gets the length in characters (not including the null terminator) of the locale name with the specified index.
- /// </summary>
- /// <param name="index">Zero-based index of the locale name.</param>
- /// <param name="length">Receives the length in characters, not including the null terminator.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetLocaleNameLength)(
- UINT32 index,
- __out UINT32* length
- ) PURE;
-
- /// <summary>
- /// Copies the locale name with the specified index to the specified array.
- /// </summary>
- /// <param name="index">Zero-based index of the locale name.</param>
- /// <param name="localeName">Character array that receives the locale name.</param>
- /// <param name="size">Size of the array in characters. The size must include space for the terminating
- /// null character.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetLocaleName)(
- UINT32 index,
- __out_ecount_z(size) WCHAR* localeName,
- UINT32 size
- ) PURE;
-
- /// <summary>
- /// Gets the length in characters (not including the null terminator) of the string with the specified index.
- /// </summary>
- /// <param name="index">Zero-based index of the string.</param>
- /// <param name="length">Receives the length in characters, not including the null terminator.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetStringLength)(
- UINT32 index,
- __out UINT32* length
- ) PURE;
-
- /// <summary>
- /// Copies the string with the specified index to the specified array.
- /// </summary>
- /// <param name="index">Zero-based index of the string.</param>
- /// <param name="stringBuffer">Character array that receives the string.</param>
- /// <param name="size">Size of the array in characters. The size must include space for the terminating
- /// null character.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetString)(
- UINT32 index,
- __out_ecount_z(size) WCHAR* stringBuffer,
- UINT32 size
- ) PURE;
-};
-
-interface IDWriteFontFamily;
-interface IDWriteFont;
-
-/// <summary>
-/// The IDWriteFontCollection encapsulates a collection of fonts.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("a84cee02-3eea-4eee-a827-87c1a02a0fcc") IDWriteFontCollection : public IUnknown
-{
- /// <summary>
- /// Gets the number of font families in the collection.
- /// </summary>
- STDMETHOD_(UINT32, GetFontFamilyCount)() PURE;
-
- /// <summary>
- /// Creates a font family object given a zero-based font family index.
- /// </summary>
- /// <param name="index">Zero-based index of the font family.</param>
- /// <param name="fontFamily">Receives a pointer the newly created font family object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontFamily)(
- UINT32 index,
- __out IDWriteFontFamily** fontFamily
- ) PURE;
-
- /// <summary>
- /// Finds the font family with the specified family name.
- /// </summary>
- /// <param name="familyName">Name of the font family. The name is not case-sensitive but must otherwise exactly match a family name in the collection.</param>
- /// <param name="index">Receives the zero-based index of the matching font family if the family name was found or UINT_MAX otherwise.</param>
- /// <param name="exists">Receives TRUE if the family name exists or FALSE otherwise.</param>
- /// <returns>
- /// Standard HRESULT error code. If the specified family name does not exist, the return value is S_OK, but *index is UINT_MAX and *exists is FALSE.
- /// </returns>
- STDMETHOD(FindFamilyName)(
- __in_z WCHAR const* familyName,
- __out UINT32* index,
- __out BOOL* exists
- ) PURE;
-
- /// <summary>
- /// Gets the font object that corresponds to the same physical font as the specified font face object. The specified physical font must belong
- /// to the font collection.
- /// </summary>
- /// <param name="fontFace">Font face object that specifies the physical font.</param>
- /// <param name="font">Receives a pointer to the newly created font object if successful or NULL otherwise.</param>
- /// <returns>
- /// Standard HRESULT error code. If the specified physical font is not part of the font collection the return value is DWRITE_E_NOFONT.
- /// </returns>
- STDMETHOD(GetFontFromFontFace)(
- IDWriteFontFace* fontFace,
- __out IDWriteFont** font
- ) PURE;
-};
-
-/// <summary>
-/// The IDWriteFontList interface represents a list of fonts.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("1a0d8438-1d97-4ec1-aef9-a2fb86ed6acb") IDWriteFontList : public IUnknown
-{
- /// <summary>
- /// Gets the font collection that contains the fonts.
- /// </summary>
- /// <param name="fontCollection">Receives a pointer to the font collection object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontCollection)(
- __out IDWriteFontCollection** fontCollection
- ) PURE;
-
- /// <summary>
- /// Gets the number of fonts in the font list.
- /// </summary>
- STDMETHOD_(UINT32, GetFontCount)() PURE;
-
- /// <summary>
- /// Gets a font given its zero-based index.
- /// </summary>
- /// <param name="index">Zero-based index of the font in the font list.</param>
- /// <param name="font">Receives a pointer to the newly created font object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFont)(
- UINT32 index,
- __out IDWriteFont** font
- ) PURE;
-};
-
-/// <summary>
-/// The IDWriteFontFamily interface represents a set of fonts that share the same design but are differentiated
-/// by weight, stretch, and style.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("da20d8ef-812a-4c43-9802-62ec4abd7add") IDWriteFontFamily : public IDWriteFontList
-{
- /// <summary>
- /// Creates an localized strings object that contains the family names for the font family, indexed by locale name.
- /// </summary>
- /// <param name="names">Receives a pointer to the newly created localized strings object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFamilyNames)(
- __out IDWriteLocalizedStrings** names
- ) PURE;
-
- /// <summary>
- /// Gets the font that best matches the specified properties.
- /// </summary>
- /// <param name="weight">Requested font weight.</param>
- /// <param name="stretch">Requested font stretch.</param>
- /// <param name="style">Requested font style.</param>
- /// <param name="matchingFont">Receives a pointer to the newly created font object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFirstMatchingFont)(
- DWRITE_FONT_WEIGHT weight,
- DWRITE_FONT_STRETCH stretch,
- DWRITE_FONT_STYLE style,
- __out IDWriteFont** matchingFont
- ) PURE;
-
- /// <summary>
- /// Gets a list of fonts in the font family ranked in order of how well they match the specified properties.
- /// </summary>
- /// <param name="weight">Requested font weight.</param>
- /// <param name="stretch">Requested font stretch.</param>
- /// <param name="style">Requested font style.</param>
- /// <param name="matchingFonts">Receives a pointer to the newly created font list object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetMatchingFonts)(
- DWRITE_FONT_WEIGHT weight,
- DWRITE_FONT_STRETCH stretch,
- DWRITE_FONT_STYLE style,
- __out IDWriteFontList** matchingFonts
- ) PURE;
-};
-
-/// <summary>
-/// The IDWriteFont interface represents a physical font in a font collection.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("acd16696-8c14-4f5d-877e-fe3fc1d32737") IDWriteFont : public IUnknown
-{
- /// <summary>
- /// Gets the font family to which the specified font belongs.
- /// </summary>
- /// <param name="fontFamily">Receives a pointer to the font family object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontFamily)(
- __out IDWriteFontFamily** fontFamily
- ) PURE;
-
- /// <summary>
- /// Gets the weight of the specified font.
- /// </summary>
- STDMETHOD_(DWRITE_FONT_WEIGHT, GetWeight)() PURE;
-
- /// <summary>
- /// Gets the stretch (aka. width) of the specified font.
- /// </summary>
- STDMETHOD_(DWRITE_FONT_STRETCH, GetStretch)() PURE;
-
- /// <summary>
- /// Gets the style (aka. slope) of the specified font.
- /// </summary>
- STDMETHOD_(DWRITE_FONT_STYLE, GetStyle)() PURE;
-
- /// <summary>
- /// Returns TRUE if the font is a symbol font or FALSE if not.
- /// </summary>
- STDMETHOD_(BOOL, IsSymbolFont)() PURE;
-
- /// <summary>
- /// Gets a localized strings collection containing the face names for the font (e.g., Regular or Bold), indexed by locale name.
- /// </summary>
- /// <param name="names">Receives a pointer to the newly created localized strings object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFaceNames)(
- __out IDWriteLocalizedStrings** names
- ) PURE;
-
- /// <summary>
- /// Gets a localized strings collection containing the specified informational strings, indexed by locale name.
- /// </summary>
- /// <param name="informationalStringID">Identifies the string to get.</param>
- /// <param name="informationalStrings">Receives a pointer to the newly created localized strings object.</param>
- /// <param name="exists">Receives the value TRUE if the font contains the specified string ID or FALSE if not.</param>
- /// <returns>
- /// Standard HRESULT error code. If the font does not contain the specified string, the return value is S_OK but
- /// informationalStrings receives a NULL pointer and exists receives the value FALSE.
- /// </returns>
- STDMETHOD(GetInformationalStrings)(
- DWRITE_INFORMATIONAL_STRING_ID informationalStringID,
- __out IDWriteLocalizedStrings** informationalStrings,
- __out BOOL* exists
- ) PURE;
-
- /// <summary>
- /// Gets a value that indicates what simulation are applied to the specified font.
- /// </summary>
- STDMETHOD_(DWRITE_FONT_SIMULATIONS, GetSimulations)() PURE;
-
- /// <summary>
- /// Gets the metrics for the font.
- /// </summary>
- /// <param name="fontMetrics">Receives the font metrics.</param>
- STDMETHOD_(void, GetMetrics)(
- __out DWRITE_FONT_METRICS* fontMetrics
- ) PURE;
-
- /// <summary>
- /// Determines whether the font supports the specified character.
- /// </summary>
- /// <param name="unicodeValue">Unicode (UCS-4) character value.</param>
- /// <param name="exists">Receives the value TRUE if the font supports the specified character or FALSE if not.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(HasCharacter)(
- UINT32 unicodeValue,
- __out BOOL* exists
- ) PURE;
-
- /// <summary>
- /// Creates a font face object for the font.
- /// </summary>
- /// <param name="fontFace">Receives a pointer to the newly created font face object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateFontFace)(
- __out IDWriteFontFace** fontFace
- ) PURE;
-};
-
-/// <summary>
-/// Direction for how reading progresses.
-/// </summary>
-enum DWRITE_READING_DIRECTION
-{
- /// <summary>
- /// Reading progresses from left to right.
- /// </summary>
- DWRITE_READING_DIRECTION_LEFT_TO_RIGHT,
-
- /// <summary>
- /// Reading progresses from right to left.
- /// </summary>
- DWRITE_READING_DIRECTION_RIGHT_TO_LEFT
-};
-
-/// <summary>
-/// Direction for how lines of text are placed relative to one another.
-/// </summary>
-enum DWRITE_FLOW_DIRECTION
-{
- /// <summary>
- /// Text lines are placed from top to bottom.
- /// </summary>
- DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM
-};
-
-/// <summary>
-/// Alignment of paragraph text along the reading direction axis relative to
-/// the leading and trailing edge of the layout box.
-/// </summary>
-enum DWRITE_TEXT_ALIGNMENT
-{
- /// <summary>
- /// The leading edge of the paragraph text is aligned to the layout box's leading edge.
- /// </summary>
- DWRITE_TEXT_ALIGNMENT_LEADING,
-
- /// <summary>
- /// The trailing edge of the paragraph text is aligned to the layout box's trailing edge.
- /// </summary>
- DWRITE_TEXT_ALIGNMENT_TRAILING,
-
- /// <summary>
- /// The center of the paragraph text is aligned to the center of the layout box.
- /// </summary>
- DWRITE_TEXT_ALIGNMENT_CENTER
-};
-
-/// <summary>
-/// Alignment of paragraph text along the flow direction axis relative to the
-/// flow's beginning and ending edge of the layout box.
-/// </summary>
-enum DWRITE_PARAGRAPH_ALIGNMENT
-{
- /// <summary>
- /// The first line of paragraph is aligned to the flow's beginning edge of the layout box.
- /// </summary>
- DWRITE_PARAGRAPH_ALIGNMENT_NEAR,
-
- /// <summary>
- /// The last line of paragraph is aligned to the flow's ending edge of the layout box.
- /// </summary>
- DWRITE_PARAGRAPH_ALIGNMENT_FAR,
-
- /// <summary>
- /// The center of the paragraph is aligned to the center of the flow of the layout box.
- /// </summary>
- DWRITE_PARAGRAPH_ALIGNMENT_CENTER
-};
-
-/// <summary>
-/// Word wrapping in multiline paragraph.
-/// </summary>
-enum DWRITE_WORD_WRAPPING
-{
- /// <summary>
- /// Words are broken across lines to avoid text overflowing the layout box.
- /// </summary>
- DWRITE_WORD_WRAPPING_WRAP,
-
- /// <summary>
- /// Words are kept within the same line even when it overflows the layout box.
- /// This option is often used with scrolling to reveal overflow text.
- /// </summary>
- DWRITE_WORD_WRAPPING_NO_WRAP
-};
-
-/// <summary>
-/// The method used for line spacing in layout.
-/// </summary>
-enum DWRITE_LINE_SPACING_METHOD
-{
- /// <summary>
- /// Line spacing depends solely on the content, growing to accomodate the size of fonts and inline objects.
- /// </summary>
- DWRITE_LINE_SPACING_METHOD_DEFAULT,
-
- /// <summary>
- /// Lines are explicitly set to uniform spacing, regardless of contained font sizes.
- /// This can be useful to avoid the uneven appearance that can occur from font fallback.
- /// </summary>
- DWRITE_LINE_SPACING_METHOD_UNIFORM
-};
-
-/// <summary>
-/// Text granularity used to trim text overflowing the layout box.
-/// </summary>
-enum DWRITE_TRIMMING_GRANULARITY
-{
- /// <summary>
- /// No trimming occurs. Text flows beyond the layout width.
- /// </summary>
- DWRITE_TRIMMING_GRANULARITY_NONE,
-
- /// <summary>
- /// Trimming occurs at character cluster boundary.
- /// </summary>
- DWRITE_TRIMMING_GRANULARITY_CHARACTER,
-
- /// <summary>
- /// Trimming occurs at word boundary.
- /// </summary>
- DWRITE_TRIMMING_GRANULARITY_WORD
-};
-
-/// <summary>
-/// Typographic feature of text supplied by the font.
-/// </summary>
-enum DWRITE_FONT_FEATURE_TAG
-{
- DWRITE_FONT_FEATURE_TAG_ALTERNATIVE_FRACTIONS = 0x63726661, // 'afrc'
- DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS_FROM_CAPITALS = 0x63703263, // 'c2pc'
- DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS_FROM_CAPITALS = 0x63733263, // 'c2sc'
- DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_ALTERNATES = 0x746c6163, // 'calt'
- DWRITE_FONT_FEATURE_TAG_CASE_SENSITIVE_FORMS = 0x65736163, // 'case'
- DWRITE_FONT_FEATURE_TAG_GLYPH_COMPOSITION_DECOMPOSITION = 0x706d6363, // 'ccmp'
- DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_LIGATURES = 0x67696c63, // 'clig'
- DWRITE_FONT_FEATURE_TAG_CAPITAL_SPACING = 0x70737063, // 'cpsp'
- DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_SWASH = 0x68777363, // 'cswh'
- DWRITE_FONT_FEATURE_TAG_CURSIVE_POSITIONING = 0x73727563, // 'curs'
- DWRITE_FONT_FEATURE_TAG_DEFAULT = 0x746c6664, // 'dflt'
- DWRITE_FONT_FEATURE_TAG_DISCRETIONARY_LIGATURES = 0x67696c64, // 'dlig'
- DWRITE_FONT_FEATURE_TAG_EXPERT_FORMS = 0x74707865, // 'expt'
- DWRITE_FONT_FEATURE_TAG_FRACTIONS = 0x63617266, // 'frac'
- DWRITE_FONT_FEATURE_TAG_FULL_WIDTH = 0x64697766, // 'fwid'
- DWRITE_FONT_FEATURE_TAG_HALF_FORMS = 0x666c6168, // 'half'
- DWRITE_FONT_FEATURE_TAG_HALANT_FORMS = 0x6e6c6168, // 'haln'
- DWRITE_FONT_FEATURE_TAG_ALTERNATE_HALF_WIDTH = 0x746c6168, // 'halt'
- DWRITE_FONT_FEATURE_TAG_HISTORICAL_FORMS = 0x74736968, // 'hist'
- DWRITE_FONT_FEATURE_TAG_HORIZONTAL_KANA_ALTERNATES = 0x616e6b68, // 'hkna'
- DWRITE_FONT_FEATURE_TAG_HISTORICAL_LIGATURES = 0x67696c68, // 'hlig'
- DWRITE_FONT_FEATURE_TAG_HALF_WIDTH = 0x64697768, // 'hwid'
- DWRITE_FONT_FEATURE_TAG_HOJO_KANJI_FORMS = 0x6f6a6f68, // 'hojo'
- DWRITE_FONT_FEATURE_TAG_JIS04_FORMS = 0x3430706a, // 'jp04'
- DWRITE_FONT_FEATURE_TAG_JIS78_FORMS = 0x3837706a, // 'jp78'
- DWRITE_FONT_FEATURE_TAG_JIS83_FORMS = 0x3338706a, // 'jp83'
- DWRITE_FONT_FEATURE_TAG_JIS90_FORMS = 0x3039706a, // 'jp90'
- DWRITE_FONT_FEATURE_TAG_KERNING = 0x6e72656b, // 'kern'
- DWRITE_FONT_FEATURE_TAG_STANDARD_LIGATURES = 0x6167696c, // 'liga'
- DWRITE_FONT_FEATURE_TAG_LINING_FIGURES = 0x6d756e6c, // 'lnum'
- DWRITE_FONT_FEATURE_TAG_LOCALIZED_FORMS = 0x6c636f6c, // 'locl'
- DWRITE_FONT_FEATURE_TAG_MARK_POSITIONING = 0x6b72616d, // 'mark'
- DWRITE_FONT_FEATURE_TAG_MATHEMATICAL_GREEK = 0x6b72676d, // 'mgrk'
- DWRITE_FONT_FEATURE_TAG_MARK_TO_MARK_POSITIONING = 0x6b6d6b6d, // 'mkmk'
- DWRITE_FONT_FEATURE_TAG_ALTERNATE_ANNOTATION_FORMS = 0x746c616e, // 'nalt'
- DWRITE_FONT_FEATURE_TAG_NLC_KANJI_FORMS = 0x6b636c6e, // 'nlck'
- DWRITE_FONT_FEATURE_TAG_OLD_STYLE_FIGURES = 0x6d756e6f, // 'onum'
- DWRITE_FONT_FEATURE_TAG_ORDINALS = 0x6e64726f, // 'ordn'
- DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_ALTERNATE_WIDTH = 0x746c6170, // 'palt'
- DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS = 0x70616370, // 'pcap'
- DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_FIGURES = 0x6d756e70, // 'pnum'
- DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_WIDTHS = 0x64697770, // 'pwid'
- DWRITE_FONT_FEATURE_TAG_QUARTER_WIDTHS = 0x64697771, // 'qwid'
- DWRITE_FONT_FEATURE_TAG_REQUIRED_LIGATURES = 0x67696c72, // 'rlig'
- DWRITE_FONT_FEATURE_TAG_RUBY_NOTATION_FORMS = 0x79627572, // 'ruby'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_ALTERNATES = 0x746c6173, // 'salt'
- DWRITE_FONT_FEATURE_TAG_SCIENTIFIC_INFERIORS = 0x666e6973, // 'sinf'
- DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS = 0x70636d73, // 'smcp'
- DWRITE_FONT_FEATURE_TAG_SIMPLIFIED_FORMS = 0x6c706d73, // 'smpl'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_1 = 0x31307373, // 'ss01'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_2 = 0x32307373, // 'ss02'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_3 = 0x33307373, // 'ss03'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_4 = 0x34307373, // 'ss04'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_5 = 0x35307373, // 'ss05'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_6 = 0x36307373, // 'ss06'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7 = 0x37307373, // 'ss07'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_8 = 0x38307373, // 'ss08'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_9 = 0x39307373, // 'ss09'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_10 = 0x30317373, // 'ss10'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_11 = 0x31317373, // 'ss11'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_12 = 0x32317373, // 'ss12'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_13 = 0x33317373, // 'ss13'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_14 = 0x34317373, // 'ss14'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_15 = 0x35317373, // 'ss15'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_16 = 0x36317373, // 'ss16'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_17 = 0x37317373, // 'ss17'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_18 = 0x38317373, // 'ss18'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_19 = 0x39317373, // 'ss19'
- DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_20 = 0x30327373, // 'ss20'
- DWRITE_FONT_FEATURE_TAG_SUBSCRIPT = 0x73627573, // 'subs'
- DWRITE_FONT_FEATURE_TAG_SUPERSCRIPT = 0x73707573, // 'sups'
- DWRITE_FONT_FEATURE_TAG_SWASH = 0x68737773, // 'swsh'
- DWRITE_FONT_FEATURE_TAG_TITLING = 0x6c746974, // 'titl'
- DWRITE_FONT_FEATURE_TAG_TRADITIONAL_NAME_FORMS = 0x6d616e74, // 'tnam'
- DWRITE_FONT_FEATURE_TAG_TABULAR_FIGURES = 0x6d756e74, // 'tnum'
- DWRITE_FONT_FEATURE_TAG_TRADITIONAL_FORMS = 0x64617274, // 'trad'
- DWRITE_FONT_FEATURE_TAG_THIRD_WIDTHS = 0x64697774, // 'twid'
- DWRITE_FONT_FEATURE_TAG_UNICASE = 0x63696e75, // 'unic'
- DWRITE_FONT_FEATURE_TAG_SLASHED_ZERO = 0x6f72657a, // 'zero'
-};
-
-/// <summary>
-/// The DWRITE_TEXT_RANGE structure specifies a range of text positions where format is applied.
-/// </summary>
-struct DWRITE_TEXT_RANGE
-{
- /// <summary>
- /// The start text position of the range.
- /// </summary>
- UINT32 startPosition;
-
- /// <summary>
- /// The number of text positions in the range.
- /// </summary>
- UINT32 length;
-};
-
-/// <summary>
-/// The DWRITE_FONT_FEATURE structure specifies properties used to identify and execute typographic feature in the font.
-/// </summary>
-struct DWRITE_FONT_FEATURE
-{
- /// <summary>
- /// The feature OpenType name identifier.
- /// </summary>
- DWRITE_FONT_FEATURE_TAG nameTag;
-
- /// <summary>
- /// Execution parameter of the feature.
- /// </summary>
- /// <remarks>
- /// The parameter should be non-zero to enable the feature. Once enabled, a feature can't be disabled again within
- /// the same range. Features requiring a selector use this value to indicate the selector index.
- /// </remarks>
- UINT32 parameter;
-};
-
-/// <summary>
-/// Defines a set of typographic features to be applied during shaping.
-/// Notice the character range which this feature list spans is specified
-/// as a separate parameter to GetGlyphs.
-/// </summary>
-struct DWRITE_TYPOGRAPHIC_FEATURES
-{
- /// <summary>
- /// Array of font features.
- /// </summary>
- __field_ecount(featureCount) DWRITE_FONT_FEATURE* features;
-
- /// <summary>
- /// The number of features.
- /// </summary>
- UINT32 featureCount;
-};
-
-/// <summary>
-/// The DWRITE_TRIMMING structure specifies the trimming option for text overflowing the layout box.
-/// </summary>
-struct DWRITE_TRIMMING
-{
- /// <summary>
- /// Text granularity of which trimming applies.
- /// </summary>
- DWRITE_TRIMMING_GRANULARITY granularity;
-
- /// <summary>
- /// Character code used as the delimiter signaling the beginning of the portion of text to be preserved,
- /// most useful for path ellipsis, where the delimeter would be a slash.
- /// </summary>
- UINT32 delimiter;
-
- /// <summary>
- /// How many occurences of the delimiter to step back.
- /// </summary>
- UINT32 delimiterCount;
-};
-
-
-interface IDWriteTypography;
-interface IDWriteInlineObject;
-
-/// <summary>
-/// The format of text used for text layout purpose.
-/// </summary>
-/// <remarks>
-/// This object may not be thread-safe and it may carry the state of text format change.
-/// </remarks>
-interface DWRITE_DECLARE_INTERFACE("9c906818-31d7-4fd3-a151-7c5e225db55a") IDWriteTextFormat : public IUnknown
-{
- /// <summary>
- /// Set alignment option of text relative to layout box's leading and trailing edge.
- /// </summary>
- /// <param name="textAlignment">Text alignment option</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetTextAlignment)(
- DWRITE_TEXT_ALIGNMENT textAlignment
- ) PURE;
-
- /// <summary>
- /// Set alignment option of paragraph relative to layout box's top and bottom edge.
- /// </summary>
- /// <param name="paragraphAlignment">Paragraph alignment option</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetParagraphAlignment)(
- DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment
- ) PURE;
-
- /// <summary>
- /// Set word wrapping option.
- /// </summary>
- /// <param name="wordWrapping">Word wrapping option</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetWordWrapping)(
- DWRITE_WORD_WRAPPING wordWrapping
- ) PURE;
-
- /// <summary>
- /// Set paragraph reading direction.
- /// </summary>
- /// <param name="readingDirection">Text reading direction</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetReadingDirection)(
- DWRITE_READING_DIRECTION readingDirection
- ) PURE;
-
- /// <summary>
- /// Set paragraph flow direction.
- /// </summary>
- /// <param name="flowDirection">Paragraph flow direction</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetFlowDirection)(
- DWRITE_FLOW_DIRECTION flowDirection
- ) PURE;
-
- /// <summary>
- /// Set incremental tab stop position.
- /// </summary>
- /// <param name="incrementalTabStop">The incremental tab stop value</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetIncrementalTabStop)(
- FLOAT incrementalTabStop
- ) PURE;
-
- /// <summary>
- /// Set trimming options for any trailing text exceeding the layout width
- /// or for any far text exceeding the layout height.
- /// </summary>
- /// <param name="trimmingOptions">Text trimming options.</param>
- /// <param name="trimmingSign">Application-defined omission sign. This parameter may be NULL if no trimming sign is desired.</param>
- /// <remarks>
- /// Any inline object can be used for the trimming sign, but CreateEllipsisTrimmingSign
- /// provides a typical ellipsis symbol. Trimming is also useful vertically for hiding
- /// partial lines.
- /// </remarks>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetTrimming)(
- __in DWRITE_TRIMMING const* trimmingOptions,
- IDWriteInlineObject* trimmingSign
- ) PURE;
-
- /// <summary>
- /// Set line spacing.
- /// </summary>
- /// <param name="lineSpacingMethod">How to determine line height.</param>
- /// <param name="lineSpacing">The line height, or rather distance between one baseline to another.</param>
- /// <param name="baseline">Distance from top of line to baseline. A reasonable ratio to lineSpacing is 80%.</param>
- /// <remarks>
- /// For the default method, spacing depends solely on the content.
- /// For uniform spacing, the given line height will override the content.
- /// </remarks>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetLineSpacing)(
- DWRITE_LINE_SPACING_METHOD lineSpacingMethod,
- FLOAT lineSpacing,
- FLOAT baseline
- ) PURE;
-
- /// <summary>
- /// Get alignment option of text relative to layout box's leading and trailing edge.
- /// </summary>
- STDMETHOD_(DWRITE_TEXT_ALIGNMENT, GetTextAlignment)() PURE;
-
- /// <summary>
- /// Get alignment option of paragraph relative to layout box's top and bottom edge.
- /// </summary>
- STDMETHOD_(DWRITE_PARAGRAPH_ALIGNMENT, GetParagraphAlignment)() PURE;
-
- /// <summary>
- /// Get word wrapping option.
- /// </summary>
- STDMETHOD_(DWRITE_WORD_WRAPPING, GetWordWrapping)() PURE;
-
- /// <summary>
- /// Get paragraph reading direction.
- /// </summary>
- STDMETHOD_(DWRITE_READING_DIRECTION, GetReadingDirection)() PURE;
-
- /// <summary>
- /// Get paragraph flow direction.
- /// </summary>
- STDMETHOD_(DWRITE_FLOW_DIRECTION, GetFlowDirection)() PURE;
-
- /// <summary>
- /// Get incremental tab stop position.
- /// </summary>
- STDMETHOD_(FLOAT, GetIncrementalTabStop)() PURE;
-
- /// <summary>
- /// Get trimming options for text overflowing the layout width.
- /// </summary>
- /// <param name="trimmingOptions">Text trimming options.</param>
- /// <param name="trimmingSign">Trimming omission sign. This parameter may be NULL.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetTrimming)(
- __out DWRITE_TRIMMING* trimmingOptions,
- __out IDWriteInlineObject** trimmingSign
- ) PURE;
-
- /// <summary>
- /// Get line spacing.
- /// </summary>
- /// <param name="lineSpacingMethod">How line height is determined.</param>
- /// <param name="lineSpacing">The line height, or rather distance between one baseline to another.</param>
- /// <param name="baseline">Distance from top of line to baseline.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetLineSpacing)(
- __out DWRITE_LINE_SPACING_METHOD* lineSpacingMethod,
- __out FLOAT* lineSpacing,
- __out FLOAT* baseline
- ) PURE;
-
- /// <summary>
- /// Get the font collection.
- /// </summary>
- /// <param name="fontCollection">The current font collection.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontCollection)(
- __out IDWriteFontCollection** fontCollection
- ) PURE;
-
- /// <summary>
- /// Get the length of the font family name, in characters, not including the terminating NULL character.
- /// </summary>
- STDMETHOD_(UINT32, GetFontFamilyNameLength)() PURE;
-
- /// <summary>
- /// Get a copy of the font family name.
- /// </summary>
- /// <param name="fontFamilyName">Character array that receives the current font family name</param>
- /// <param name="nameSize">Size of the character array in character count including the terminated NULL character.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontFamilyName)(
- __out_ecount_z(nameSize) WCHAR* fontFamilyName,
- UINT32 nameSize
- ) PURE;
-
- /// <summary>
- /// Get the font weight.
- /// </summary>
- STDMETHOD_(DWRITE_FONT_WEIGHT, GetFontWeight)() PURE;
-
- /// <summary>
- /// Get the font style.
- /// </summary>
- STDMETHOD_(DWRITE_FONT_STYLE, GetFontStyle)() PURE;
-
- /// <summary>
- /// Get the font stretch.
- /// </summary>
- STDMETHOD_(DWRITE_FONT_STRETCH, GetFontStretch)() PURE;
-
- /// <summary>
- /// Get the font em height.
- /// </summary>
- STDMETHOD_(FLOAT, GetFontSize)() PURE;
-
- /// <summary>
- /// Get the length of the locale name, in characters, not including the terminating NULL character.
- /// </summary>
- STDMETHOD_(UINT32, GetLocaleNameLength)() PURE;
-
- /// <summary>
- /// Get a copy of the locale name.
- /// </summary>
- /// <param name="localeName">Character array that receives the current locale name</param>
- /// <param name="nameSize">Size of the character array in character count including the terminated NULL character.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetLocaleName)(
- __out_ecount_z(nameSize) WCHAR* localeName,
- UINT32 nameSize
- ) PURE;
-};
-
-
-/// <summary>
-/// Font typography setting.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("55f1112b-1dc2-4b3c-9541-f46894ed85b6") IDWriteTypography : public IUnknown
-{
- /// <summary>
- /// Add font feature.
- /// </summary>
- /// <param name="fontFeature">The font feature to add.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(AddFontFeature)(
- DWRITE_FONT_FEATURE fontFeature
- ) PURE;
-
- /// <summary>
- /// Get the number of font features.
- /// </summary>
- STDMETHOD_(UINT32, GetFontFeatureCount)() PURE;
-
- /// <summary>
- /// Get the font feature at the specified index.
- /// </summary>
- /// <param name="fontFeatureIndex">The zero-based index of the font feature to get.</param>
- /// <param name="fontFeature">The font feature.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontFeature)(
- UINT32 fontFeatureIndex,
- __out DWRITE_FONT_FEATURE* fontFeature
- ) PURE;
-};
-
-enum DWRITE_SCRIPT_SHAPES
-{
- /// <summary>
- /// No additional shaping requirement. Text is shaped with the writing system default behavior.
- /// </summary>
- DWRITE_SCRIPT_SHAPES_DEFAULT = 0,
-
- /// <summary>
- /// Text should leave no visual on display i.e. control or format control characters.
- /// </summary>
- DWRITE_SCRIPT_SHAPES_NO_VISUAL = 1
-};
-
-#ifdef DEFINE_ENUM_FLAG_OPERATORS
-DEFINE_ENUM_FLAG_OPERATORS(DWRITE_SCRIPT_SHAPES);
-#endif
-
-/// <summary>
-/// Association of text and its writing system script as well as some display attributes.
-/// </summary>
-struct DWRITE_SCRIPT_ANALYSIS
-{
- /// <summary>
- /// Zero-based index representation of writing system script.
- /// </summary>
- UINT16 script;
-
- /// <summary>
- /// Additional shaping requirement of text.
- /// </summary>
- DWRITE_SCRIPT_SHAPES shapes;
-};
-
-/// <summary>
-/// Condition at the edges of inline object or text used to determine
-/// line-breaking behavior.
-/// </summary>
-enum DWRITE_BREAK_CONDITION
-{
- /// <summary>
- /// Whether a break is allowed is determined by the condition of the
- /// neighboring text span or inline object.
- /// </summary>
- DWRITE_BREAK_CONDITION_NEUTRAL,
-
- /// <summary>
- /// A break is allowed, unless overruled by the condition of the
- /// neighboring text span or inline object, either prohibited by a
- /// May Not or forced by a Must.
- /// </summary>
- DWRITE_BREAK_CONDITION_CAN_BREAK,
-
- /// <summary>
- /// There should be no break, unless overruled by a Must condition from
- /// the neighboring text span or inline object.
- /// </summary>
- DWRITE_BREAK_CONDITION_MAY_NOT_BREAK,
-
- /// <summary>
- /// The break must happen, regardless of the condition of the adjacent
- /// text span or inline object.
- /// </summary>
- DWRITE_BREAK_CONDITION_MUST_BREAK
-};
-
-/// <summary>
-/// Line breakpoint characteristics of a character.
-/// </summary>
-struct DWRITE_LINE_BREAKPOINT
-{
- /// <summary>
- /// Breaking condition before the character.
- /// </summary>
- UINT8 breakConditionBefore : 2;
-
- /// <summary>
- /// Breaking condition after the character.
- /// </summary>
- UINT8 breakConditionAfter : 2;
-
- /// <summary>
- /// The character is some form of whitespace, which may be meaningful
- /// for justification.
- /// </summary>
- UINT8 isWhitespace : 1;
-
- /// <summary>
- /// The character is a soft hyphen, often used to indicate hyphenation
- /// points inside words.
- /// </summary>
- UINT8 isSoftHyphen : 1;
-
- UINT8 padding : 2;
-};
-
-/// <summary>
-/// How to apply number substitution on digits and related punctuation.
-/// </summary>
-enum DWRITE_NUMBER_SUBSTITUTION_METHOD
-{
- /// <summary>
- /// Specifies that the substitution method should be determined based
- /// on LOCALE_IDIGITSUBSTITUTION value of the specified text culture.
- /// </summary>
- DWRITE_NUMBER_SUBSTITUTION_METHOD_FROM_CULTURE,
-
- /// <summary>
- /// If the culture is Arabic or Farsi, specifies that the number shape
- /// depend on the context. Either traditional or nominal number shape
- /// are used depending on the nearest preceding strong character or (if
- /// there is none) the reading direction of the paragraph.
- /// </summary>
- DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL,
-
- /// <summary>
- /// Specifies that code points 0x30-0x39 are always rendered as nominal numeral
- /// shapes (ones of the European number), i.e., no substitution is performed.
- /// </summary>
- DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE,
-
- /// <summary>
- /// Specifies that number are rendered using the national number shape
- /// as specified by the LOCALE_SNATIVEDIGITS value of the specified text culture.
- /// </summary>
- DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL,
-
- /// <summary>
- /// Specifies that number are rendered using the traditional shape
- /// for the specified culture. For most cultures, this is the same as
- /// NativeNational. However, NativeNational results in Latin number
- /// for some Arabic cultures, whereas this value results in Arabic
- /// number for all Arabic cultures.
- /// </summary>
- DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL
-};
-
-/// <summary>
-/// Holds the appropriate digits and numeric punctuation for a given locale.
-/// </summary>
-interface DECLSPEC_UUID("14885CC9-BAB0-4f90-B6ED-5C366A2CD03D") DECLSPEC_NOVTABLE IDWriteNumberSubstitution : public IUnknown
-{
-};
-
-/// <summary>
-/// Shaping output properties per input character.
-/// </summary>
-struct DWRITE_SHAPING_TEXT_PROPERTIES
-{
- /// <summary>
- /// This character can be shaped independently from the others
- /// (usually set for the space character).
- /// </summary>
- UINT16 isShapedAlone : 1;
-
- /// <summary>
- /// Reserved for use by shaping engine.
- /// </summary>
- UINT16 reserved : 15;
-};
-
-/// <summary>
-/// Shaping output properties per output glyph.
-/// </summary>
-struct DWRITE_SHAPING_GLYPH_PROPERTIES
-{
- /// <summary>
- /// Justification class, whether to use spacing, kashidas, or
- /// another method. This exists for backwards compatibility
- /// with Uniscribe's SCRIPT_JUSTIFY enum.
- /// </summary>
- UINT16 justification : 4;
-
- /// <summary>
- /// Indicates glyph is the first of a cluster.
- /// </summary>
- UINT16 isClusterStart : 1;
-
- /// <summary>
- /// Glyph is a diacritic.
- /// </summary>
- UINT16 isDiacritic : 1;
-
- /// <summary>
- /// Glyph has no width, blank, ZWJ, ZWNJ etc.
- /// </summary>
- UINT16 isZeroWidthSpace : 1;
-
- /// <summary>
- /// Reserved for use by shaping engine.
- /// </summary>
- UINT16 reserved : 9;
-};
-
-/// <summary>
-/// The interface implemented by the text analyzer's client to provide text to
-/// the analyzer. It allows the separation between the logical view of text as
-/// a continuous stream of characters identifiable by unique text positions,
-/// and the actual memory layout of potentially discrete blocks of text in the
-/// client's backing store.
-///
-/// If any of these callbacks returns an error, the analysis functions will
-/// stop prematurely and return a callback error. Rather than return E_NOTIMPL,
-/// an application should stub the method and return a constant/null and S_OK.
-/// </summary>
-interface DECLSPEC_UUID("688e1a58-5094-47c8-adc8-fbcea60ae92b") DECLSPEC_NOVTABLE IDWriteTextAnalysisSource : public IUnknown
-{
- /// <summary>
- /// Get a block of text starting at the specified text position.
- /// Returning NULL indicates the end of text - the position is after
- /// the last character. This function is called iteratively for
- /// each consecutive block, tying together several fragmented blocks
- /// in the backing store into a virtual contiguous string.
- /// </summary>
- /// <param name="textPosition">First position of the piece to obtain. All
- /// positions are in UTF16 code-units, not whole characters, which
- /// matters when supplementary characters are used.</param>
- /// <param name="textString">Address that receives a pointer to the text block
- /// at the specified position.</param>
- /// <param name="textLength">Number of UTF16 units of the retrieved chunk.
- /// The returned length is not the length of the block, but the length
- /// remaining in the block, from the given position until its end.
- /// So querying for a position that is 75 positions into a 100
- /// postition block would return 25.</param>
- /// <returns>Pointer to the first character at the given text position.
- /// NULL indicates no chunk available at the specified position, either
- /// because textPosition >= the entire text content length or because the
- /// queried position is not mapped into the app's backing store.</returns>
- /// <remarks>
- /// Although apps can implement sparse textual content that only maps part of
- /// the backing store, the app must map any text that is in the range passed
- /// to any analysis functions.
- /// </remarks>
- STDMETHOD(GetTextAtPosition)(
- UINT32 textPosition,
- __out WCHAR const** textString,
- __out UINT32* textLength
- ) PURE;
-
- /// <summary>
- /// Get a block of text immediately preceding the specified position.
- /// </summary>
- /// <param name="textPosition">Position immediately after the last position of the chunk to obtain.</param>
- /// <param name="textString">Address that receives a pointer to the text block
- /// at the specified position.</param>
- /// <param name="textLength">Number of UTF16 units of the retrieved block.
- /// The length returned is from the given position to the front of
- /// the block.</param>
- /// <returns>Pointer to the first character at (textPosition - textLength).
- /// NULL indicates no chunk available at the specified position, either
- /// because textPosition == 0,the textPosition > the entire text content
- /// length, or the queried position is not mapped into the app's backing
- /// store.</returns>
- /// <remarks>
- /// Although apps can implement sparse textual content that only maps part of
- /// the backing store, the app must map any text that is in the range passed
- /// to any analysis functions.
- /// </remarks>
- STDMETHOD(GetTextBeforePosition)(
- UINT32 textPosition,
- __out WCHAR const** textString,
- __out UINT32* textLength
- ) PURE;
-
- /// <summary>
- /// Get paragraph reading direction.
- /// </summary>
- STDMETHOD_(DWRITE_READING_DIRECTION, GetParagraphReadingDirection)() PURE;
-
- /// <summary>
- /// Get locale name on the range affected by it.
- /// </summary>
- /// <param name="textPosition">Position to get the locale name of.</param>
- /// <param name="textLength">Receives the length from the given position up to the
- /// next differing locale.</param>
- /// <param name="localeName">Address that receives a pointer to the locale
- /// at the specified position.</param>
- /// <remarks>
- /// The localeName pointer must remain valid until the next call or until
- /// the analysis returns.
- /// </remarks>
- STDMETHOD(GetLocaleName)(
- UINT32 textPosition,
- __out UINT32* textLength,
- __out_z WCHAR const** localeName
- ) PURE;
-
- /// <summary>
- /// Get number substitution on the range affected by it.
- /// </summary>
- /// <param name="textPosition">Position to get the number substitution of.</param>
- /// <param name="textLength">Receives the length from the given position up to the
- /// next differing number substitution.</param>
- /// <param name="numberSubstitution">Address that receives a pointer to the number substitution
- /// at the specified position.</param>
- /// <remarks>
- /// Any implementation should return the number substitution with an
- /// incremented ref count, and the analysis will release when finished
- /// with it (either before the next call or before it returns). However,
- /// the sink callback may hold onto it after that.
- /// </remarks>
- STDMETHOD(GetNumberSubstitution)(
- UINT32 textPosition,
- __out UINT32* textLength,
- __out IDWriteNumberSubstitution** numberSubstitution
- ) PURE;
-};
-
-/// <summary>
-/// The interface implemented by the text analyzer's client to receive the
-/// output of a given text analysis. The Text analyzer disregards any current
-/// state of the analysis sink, therefore a Set method call on a range
-/// overwrites the previously set analysis result of the same range.
-/// </summary>
-interface DECLSPEC_UUID("5810cd44-0ca0-4701-b3fa-bec5182ae4f6") DECLSPEC_NOVTABLE IDWriteTextAnalysisSink : public IUnknown
-{
- /// <summary>
- /// Report script analysis for the text range.
- /// </summary>
- /// <param name="textPosition">Starting position to report from.</param>
- /// <param name="textLength">Number of UTF16 units of the reported range.</param>
- /// <param name="scriptAnalysis">Script analysis of characters in range.</param>
- /// <returns>
- /// A successful code or error code to abort analysis.
- /// </returns>
- STDMETHOD(SetScriptAnalysis)(
- UINT32 textPosition,
- UINT32 textLength,
- __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis
- ) PURE;
-
- /// <summary>
- /// Repport line-break opportunities for each character, starting from
- /// the specified position.
- /// </summary>
- /// <param name="textPosition">Starting position to report from.</param>
- /// <param name="textLength">Number of UTF16 units of the reported range.</param>
- /// <param name="lineBreakpoints">Breaking conditions for each character.</param>
- /// <returns>
- /// A successful code or error code to abort analysis.
- /// </returns>
- STDMETHOD(SetLineBreakpoints)(
- UINT32 textPosition,
- UINT32 textLength,
- __in_ecount(textLength) DWRITE_LINE_BREAKPOINT const* lineBreakpoints
- ) PURE;
-
- /// <summary>
- /// Set bidirectional level on the range, called once per each
- /// level run change (either explicit or resolved implicit).
- /// </summary>
- /// <param name="textPosition">Starting position to report from.</param>
- /// <param name="textLength">Number of UTF16 units of the reported range.</param>
- /// <param name="explicitLevel">Explicit level from embedded control codes
- /// RLE/RLO/LRE/LRO/PDF, determined before any additional rules.</param>
- /// <param name="resolvedLevel">Final implicit level considering the
- /// explicit level and characters' natural directionality, after all
- /// Bidi rules have been applied.</param>
- /// <returns>
- /// A successful code or error code to abort analysis.
- /// </returns>
- STDMETHOD(SetBidiLevel)(
- UINT32 textPosition,
- UINT32 textLength,
- UINT8 explicitLevel,
- UINT8 resolvedLevel
- ) PURE;
-
- /// <summary>
- /// Set number substitution on the range.
- /// </summary>
- /// <param name="textPosition">Starting position to report from.</param>
- /// <param name="textLength">Number of UTF16 units of the reported range.</param>
- /// <param name="numberSubstitution">The number substitution applicable to
- /// the returned range of text. The sink callback may hold onto it by
- /// incrementing its ref count.</param>
- /// <returns>
- /// A successful code or error code to abort analysis.
- /// </returns>
- /// <remark>
- /// Unlike script and bidi analysis, where every character passed to the
- /// analyzer has a result, this will only be called for those ranges where
- /// substitution is applicable. For any other range, you will simply not
- /// be called.
- /// </remark>
- STDMETHOD(SetNumberSubstitution)(
- UINT32 textPosition,
- UINT32 textLength,
- __notnull IDWriteNumberSubstitution* numberSubstitution
- ) PURE;
-};
-
-/// <summary>
-/// Analyzes various text properties for complex script processing.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("b7e6163e-7f46-43b4-84b3-e4e6249c365d") IDWriteTextAnalyzer : public IUnknown
-{
- /// <summary>
- /// Analyzes a text range for script boundaries, reading text attributes
- /// from the source and reporting the Unicode script ID to the sink
- /// callback SetScript.
- /// </summary>
- /// <param name="analysisSource">Source object to analyze.</param>
- /// <param name="textPosition">Starting position within the source object.</param>
- /// <param name="textLength">Length to analyze.</param>
- /// <param name="analysisSink">Callback object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(AnalyzeScript)(
- IDWriteTextAnalysisSource* analysisSource,
- UINT32 textPosition,
- UINT32 textLength,
- IDWriteTextAnalysisSink* analysisSink
- ) PURE;
-
- /// <summary>
- /// Analyzes a text range for script directionality, reading attributes
- /// from the source and reporting levels to the sink callback SetBidiLevel.
- /// </summary>
- /// <param name="analysisSource">Source object to analyze.</param>
- /// <param name="textPosition">Starting position within the source object.</param>
- /// <param name="textLength">Length to analyze.</param>
- /// <param name="analysisSink">Callback object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// While the function can handle multiple paragraphs, the text range
- /// should not arbitrarily split the middle of paragraphs. Otherwise the
- /// returned levels may be wrong, since the Bidi algorithm is meant to
- /// apply to the paragraph as a whole.
- /// </remarks>
- /// <remarks>
- /// Embedded control codes (LRE/LRO/RLE/RLO/PDF) are taken into account.
- /// </remarks>
- STDMETHOD(AnalyzeBidi)(
- IDWriteTextAnalysisSource* analysisSource,
- UINT32 textPosition,
- UINT32 textLength,
- IDWriteTextAnalysisSink* analysisSink
- ) PURE;
-
- /// <summary>
- /// Analyzes a text range for spans where number substitution is applicable,
- /// reading attributes from the source and reporting substitutable ranges
- /// to the sink callback SetNumberSubstitution.
- /// </summary>
- /// <param name="analysisSource">Source object to analyze.</param>
- /// <param name="textPosition">Starting position within the source object.</param>
- /// <param name="textLength">Length to analyze.</param>
- /// <param name="analysisSink">Callback object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// While the function can handle multiple ranges of differing number
- /// substitutions, the text ranges should not arbitrarily split the
- /// middle of numbers. Otherwise it will treat the numbers separately
- /// and will not translate any intervening punctuation.
- /// </remarks>
- /// <remarks>
- /// Embedded control codes (LRE/LRO/RLE/RLO/PDF) are taken into account.
- /// </remarks>
- STDMETHOD(AnalyzeNumberSubstitution)(
- IDWriteTextAnalysisSource* analysisSource,
- UINT32 textPosition,
- UINT32 textLength,
- IDWriteTextAnalysisSink* analysisSink
- ) PURE;
-
- /// <summary>
- /// Analyzes a text range for potential breakpoint opportunities, reading
- /// attributes from the source and reporting breakpoint opportunities to
- /// the sink callback SetLineBreakpoints.
- /// </summary>
- /// <param name="analysisSource">Source object to analyze.</param>
- /// <param name="textPosition">Starting position within the source object.</param>
- /// <param name="textLength">Length to analyze.</param>
- /// <param name="analysisSink">Callback object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// While the function can handle multiple paragraphs, the text range
- /// should not arbitrarily split the middle of paragraphs, unless the
- /// given text span is considered a whole unit. Otherwise the
- /// returned properties for the first and last characters will
- /// inappropriately allow breaks.
- /// </remarks>
- /// <remarks>
- /// Special cases include the first, last, and surrogate characters. Any
- /// text span is treated as if adjacent to inline objects on either side.
- /// So the rules with contingent-break opportunities are used, where the
- /// edge between text and inline objects is always treated as a potential
- /// break opportunity, dependent on any overriding rules of the adjacent
- /// objects to prohibit or force the break (see Unicode TR #14).
- /// Surrogate pairs never break between.
- /// </remarks>
- STDMETHOD(AnalyzeLineBreakpoints)(
- IDWriteTextAnalysisSource* analysisSource,
- UINT32 textPosition,
- UINT32 textLength,
- IDWriteTextAnalysisSink* analysisSink
- ) PURE;
-
- /// <summary>
- /// Parses the input text string and maps it to the set of glyphs and associated glyph data
- /// according to the font and the writing system's rendering rules.
- /// </summary>
- /// <param name="textString">The string to convert to glyphs.</param>
- /// <param name="textLength">The length of textString.</param>
- /// <param name="fontFace">The font face to get glyphs from.</param>
- /// <param name="isSideways">Set to true if the text is intended to be
- /// drawn vertically.</param>
- /// <param name="isRightToLeft">Set to TRUE for right-to-left text.</param>
- /// <param name="scriptAnalysis">Script analysis result from AnalyzeScript.</param>
- /// <param name="localeName">The locale to use when selecting glyphs.
- /// e.g. the same character may map to different glyphs for ja-jp vs zh-chs.
- /// If this is NULL then the default mapping based on the script is used.</param>
- /// <param name="numberSubstitution">Optional number substitution which
- /// selects the appropriate glyphs for digits and related numeric characters,
- /// depending on the results obtained from AnalyzeNumberSubstitution. Passing
- /// null indicates that no substitution is needed and that the digits should
- /// receive nominal glyphs.</param>
- /// <param name="features">An array of pointers to the sets of typographic
- /// features to use in each feature range.</param>
- /// <param name="featureRangeLengths">The length of each feature range, in characters.
- /// The sum of all lengths should be equal to textLength.</param>
- /// <param name="featureRanges">The number of feature ranges.</param>
- /// <param name="maxGlyphCount">The maximum number of glyphs that can be
- /// returned.</param>
- /// <param name="clusterMap">The mapping from character ranges to glyph
- /// ranges.</param>
- /// <param name="textProps">Per-character output properties.</param>
- /// <param name="glyphIndices">Output glyph indices.</param>
- /// <param name="glyphProps">Per-glyph output properties.</param>
- /// <param name="actualGlyphCount">The actual number of glyphs returned if
- /// the call succeeds.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// Note that the mapping from characters to glyphs is, in general, many-
- /// to-many. The recommended estimate for the per-glyph output buffers is
- /// (3 * textLength / 2 + 16). This is not guaranteed to be sufficient.
- ///
- /// The value of the actualGlyphCount parameter is only valid if the call
- /// succeeds. In the event that maxGlyphCount is not big enough
- /// E_NOT_SUFFICIENT_BUFFER, which is equivalent to HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
- /// will be returned. The application should allocate a larger buffer and try again.
- /// </remarks>
- STDMETHOD(GetGlyphs)(
- __in_ecount(textLength) WCHAR const* textString,
- UINT32 textLength,
- IDWriteFontFace* fontFace,
- BOOL isSideways,
- BOOL isRightToLeft,
- __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
- __in_z_opt WCHAR const* localeName,
- __maybenull IDWriteNumberSubstitution* numberSubstitution,
- __in_ecount_opt(featureRanges) DWRITE_TYPOGRAPHIC_FEATURES const** features,
- __in_ecount_opt(featureRanges) UINT32 const* featureRangeLengths,
- UINT32 featureRanges,
- UINT32 maxGlyphCount,
- __out_ecount(textLength) UINT16* clusterMap,
- __out_ecount(textLength) DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
- __out_ecount(maxGlyphCount) UINT16* glyphIndices,
- __out_ecount(maxGlyphCount) DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProps,
- __out UINT32* actualGlyphCount
- ) PURE;
-
- /// <summary>
- /// Place glyphs output from the GetGlyphs method according to the font
- /// and the writing system's rendering rules.
- /// </summary>
- /// <param name="textString">The original string the glyphs came from.</param>
- /// <param name="clusterMap">The mapping from character ranges to glyph
- /// ranges. Returned by GetGlyphs.</param>
- /// <param name="textProps">Per-character properties. Returned by
- /// GetGlyphs.</param>
- /// <param name="textLength">The length of textString.</param>
- /// <param name="glyphIndices">Glyph indices. See GetGlyphs</param>
- /// <param name="glyphProps">Per-glyph properties. See GetGlyphs</param>
- /// <param name="glyphCount">The number of glyphs.</param>
- /// <param name="fontFace">The font face the glyphs came from.</param>
- /// <param name="fontEmSize">Logical font size in DIP's.</param>
- /// <param name="isSideways">Set to true if the text is intended to be
- /// drawn vertically.</param>
- /// <param name="isRightToLeft">Set to TRUE for right-to-left text.</param>
- /// <param name="scriptAnalysis">Script analysis result from AnalyzeScript.</param>
- /// <param name="localeName">The locale to use when selecting glyphs.
- /// e.g. the same character may map to different glyphs for ja-jp vs zh-chs.
- /// If this is NULL then the default mapping based on the script is used.</param>
- /// <param name="features">An array of pointers to the sets of typographic
- /// features to use in each feature range.</param>
- /// <param name="featureRangeLengths">The length of each feature range, in characters.
- /// The sum of all lengths should be equal to textLength.</param>
- /// <param name="featureRanges">The number of feature ranges.</param>
- /// <param name="glyphAdvances">The advance width of each glyph.</param>
- /// <param name="glyphOffsets">The offset of the origin of each glyph.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetGlyphPlacements)(
- __in_ecount(textLength) WCHAR const* textString,
- __in_ecount(textLength) UINT16 const* clusterMap,
- __in_ecount(textLength) DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
- UINT32 textLength,
- __in_ecount(glyphCount) UINT16 const* glyphIndices,
- __in_ecount(glyphCount) DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps,
- UINT32 glyphCount,
- IDWriteFontFace * fontFace,
- FLOAT fontEmSize,
- BOOL isSideways,
- BOOL isRightToLeft,
- __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
- __in_z_opt WCHAR const* localeName,
- __in_ecount_opt(featureRanges) DWRITE_TYPOGRAPHIC_FEATURES const** features,
- __in_ecount_opt(featureRanges) UINT32 const* featureRangeLengths,
- UINT32 featureRanges,
- __out_ecount(glyphCount) FLOAT* glyphAdvances,
- __out_ecount(glyphCount) DWRITE_GLYPH_OFFSET* glyphOffsets
- ) PURE;
-
- /// <summary>
- /// Place glyphs output from the GetGlyphs method according to the font
- /// and the writing system's rendering rules.
- /// </summary>
- /// <param name="textString">The original string the glyphs came from.</param>
- /// <param name="clusterMap">The mapping from character ranges to glyph
- /// ranges. Returned by GetGlyphs.</param>
- /// <param name="textProps">Per-character properties. Returned by
- /// GetGlyphs.</param>
- /// <param name="textLength">The length of textString.</param>
- /// <param name="glyphIndices">Glyph indices. See GetGlyphs</param>
- /// <param name="glyphProps">Per-glyph properties. See GetGlyphs</param>
- /// <param name="glyphCount">The number of glyphs.</param>
- /// <param name="fontFace">The font face the glyphs came from.</param>
- /// <param name="fontEmSize">Logical font size in DIP's.</param>
- /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this
- /// value is 1.0f. If the DPI is 120, this value is 120.0f/96.</param>
- /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
- /// scaling specified by the font size and pixelsPerDip.</param>
- /// <param name="useGdiNatural">
- /// When set to FALSE, the metrics are the same as the metrics of GDI aliased text.
- /// When set to TRUE, the metrics are the same as the metrics of text measured by GDI using a font
- /// created with CLEARTYPE_NATURAL_QUALITY.
- /// </param>
- /// <param name="isSideways">Set to true if the text is intended to be
- /// drawn vertically.</param>
- /// <param name="isRightToLeft">Set to TRUE for right-to-left text.</param>
- /// <param name="scriptAnalysis">Script analysis result from AnalyzeScript.</param>
- /// <param name="localeName">The locale to use when selecting glyphs.
- /// e.g. the same character may map to different glyphs for ja-jp vs zh-chs.
- /// If this is NULL then the default mapping based on the script is used.</param>
- /// <param name="features">An array of pointers to the sets of typographic
- /// features to use in each feature range.</param>
- /// <param name="featureRangeLengths">The length of each feature range, in characters.
- /// The sum of all lengths should be equal to textLength.</param>
- /// <param name="featureRanges">The number of feature ranges.</param>
- /// <param name="glyphAdvances">The advance width of each glyph.</param>
- /// <param name="glyphOffsets">The offset of the origin of each glyph.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetGdiCompatibleGlyphPlacements)(
- __in_ecount(textLength) WCHAR const* textString,
- __in_ecount(textLength) UINT16 const* clusterMap,
- __in_ecount(textLength) DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
- UINT32 textLength,
- __in_ecount(glyphCount) UINT16 const* glyphIndices,
- __in_ecount(glyphCount) DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps,
- UINT32 glyphCount,
- IDWriteFontFace * fontFace,
- FLOAT fontEmSize,
- FLOAT pixelsPerDip,
- __in_opt DWRITE_MATRIX const* transform,
- BOOL useGdiNatural,
- BOOL isSideways,
- BOOL isRightToLeft,
- __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
- __in_z_opt WCHAR const* localeName,
- __in_ecount_opt(featureRanges) DWRITE_TYPOGRAPHIC_FEATURES const** features,
- __in_ecount_opt(featureRanges) UINT32 const* featureRangeLengths,
- UINT32 featureRanges,
- __out_ecount(glyphCount) FLOAT* glyphAdvances,
- __out_ecount(glyphCount) DWRITE_GLYPH_OFFSET* glyphOffsets
- ) PURE;
-};
-
-/// <summary>
-/// The DWRITE_GLYPH_RUN structure contains the information needed by renderers
-/// to draw glyph runs. All coordinates are in device independent pixels (DIPs).
-/// </summary>
-struct DWRITE_GLYPH_RUN
-{
- /// <summary>
- /// The physical font face to draw with.
- /// </summary>
- __notnull IDWriteFontFace* fontFace;
-
- /// <summary>
- /// Logical size of the font in DIPs, not points (equals 1/96 inch).
- /// </summary>
- FLOAT fontEmSize;
-
- /// <summary>
- /// The number of glyphs.
- /// </summary>
- UINT32 glyphCount;
-
- /// <summary>
- /// The indices to render.
- /// </summary>
- __field_ecount(glyphCount) UINT16 const* glyphIndices;
-
- /// <summary>
- /// Glyph advance widths.
- /// </summary>
- __field_ecount_opt(glyphCount) FLOAT const* glyphAdvances;
-
- /// <summary>
- /// Glyph offsets.
- /// </summary>
- __field_ecount_opt(glyphCount) DWRITE_GLYPH_OFFSET const* glyphOffsets;
-
- /// <summary>
- /// If true, specifies that glyphs are rotated 90 degrees to the left and
- /// vertical metrics are used. Vertical writing is achieved by specifying
- /// isSideways = true and rotating the entire run 90 degrees to the right
- /// via a rotate transform.
- /// </summary>
- BOOL isSideways;
-
- /// <summary>
- /// The implicit resolved bidi level of the run. Odd levels indicate
- /// right-to-left languages like Hebrew and Arabic, while even levels
- /// indicate left-to-right languages like English and Japanese (when
- /// written horizontally). For right-to-left languages, the text origin
- /// is on the right, and text should be drawn to the left.
- /// </summary>
- UINT32 bidiLevel;
-};
-
-/// <summary>
-/// The DWRITE_GLYPH_RUN_DESCRIPTION structure contains additional properties
-/// related to those in DWRITE_GLYPH_RUN.
-/// </summary>
-struct DWRITE_GLYPH_RUN_DESCRIPTION
-{
- /// <summary>
- /// The locale name associated with this run.
- /// </summary>
- __nullterminated WCHAR const* localeName;
-
- /// <summary>
- /// The text associated with the glyphs.
- /// </summary>
- __field_ecount(stringLength) WCHAR const* string;
-
- /// <summary>
- /// The number of characters (UTF16 code-units).
- /// Note that this may be different than the number of glyphs.
- /// </summary>
- UINT32 stringLength;
-
- /// <summary>
- /// An array of indices to the glyph indices array, of the first glyphs of
- /// all the glyph clusters of the glyphs to render.
- /// </summary>
- __field_ecount(stringLength) UINT16 const* clusterMap;
-
- /// <summary>
- /// Corresponding text position in the original string
- /// this glyph run came from.
- /// </summary>
- UINT32 textPosition;
-};
-
-/// <summary>
-/// The DWRITE_UNDERLINE structure contains about the size and placement of
-/// underlines. All coordinates are in device independent pixels (DIPs).
-/// </summary>
-struct DWRITE_UNDERLINE
-{
- /// <summary>
- /// Width of the underline, measured parallel to the baseline.
- /// </summary>
- FLOAT width;
-
- /// <summary>
- /// Thickness of the underline, measured perpendicular to the
- /// baseline.
- /// </summary>
- FLOAT thickness;
-
- /// <summary>
- /// Offset of the underline from the baseline.
- /// A positive offset represents a position below the baseline and
- /// a negative offset is above.
- /// </summary>
- FLOAT offset;
-
- /// <summary>
- /// Height of the tallest run where the underline applies.
- /// </summary>
- FLOAT runHeight;
-
- /// <summary>
- /// Reading direction of the text associated with the underline. This
- /// value is used to interpret whether the width value runs horizontally
- /// or vertically.
- /// </summary>
- DWRITE_READING_DIRECTION readingDirection;
-
- /// <summary>
- /// Flow direction of the text associated with the underline. This value
- /// is used to interpret whether the thickness value advances top to
- /// bottom, left to right, or right to left.
- /// </summary>
- DWRITE_FLOW_DIRECTION flowDirection;
-
- /// <summary>
- /// Locale of the text the underline is being drawn under. Can be
- /// pertinent where the locale affects how the underline is drawn.
- /// For example, in vertical text, the underline belongs on the
- /// left for Chinese but on the right for Japanese.
- /// This choice is completely left up to higher levels.
- /// </summary>
- __nullterminated WCHAR const* localeName;
-
- /// <summary>
- /// The measuring mode can be useful to the renderer to determine how
- /// underlines are rendered, e.g. rounding the thickness to a whole pixel
- /// in GDI-compatible modes.
- /// </summary>
- DWRITE_MEASURING_MODE measuringMode;
-};
-
-/// <summary>
-/// The DWRITE_STRIKETHROUGH structure contains about the size and placement of
-/// strickthroughs. All coordinates are in device independent pixels (DIPs).
-/// </summary>
-struct DWRITE_STRIKETHROUGH
-{
- /// <summary>
- /// Width of the strikethrough, measured parallel to the baseline.
- /// </summary>
- FLOAT width;
-
- /// <summary>
- /// Thickness of the strikethrough, measured perpendicular to the
- /// baseline.
- /// </summary>
- FLOAT thickness;
-
- /// <summary>
- /// Offset of the stikethrough from the baseline.
- /// A positive offset represents a position below the baseline and
- /// a negative offset is above.
- /// </summary>
- FLOAT offset;
-
- /// <summary>
- /// Reading direction of the text associated with the strikethrough. This
- /// value is used to interpret whether the width value runs horizontally
- /// or vertically.
- /// </summary>
- DWRITE_READING_DIRECTION readingDirection;
-
- /// <summary>
- /// Flow direction of the text associated with the strikethrough. This
- /// value is used to interpret whether the thickness value advances top to
- /// bottom, left to right, or right to left.
- /// </summary>
- DWRITE_FLOW_DIRECTION flowDirection;
-
- /// <summary>
- /// Locale of the range. Can be pertinent where the locale affects the style.
- /// </summary>
- __nullterminated WCHAR const* localeName;
-
- /// <summary>
- /// The measuring mode can be useful to the renderer to determine how
- /// underlines are rendered, e.g. rounding the thickness to a whole pixel
- /// in GDI-compatible modes.
- /// </summary>
- DWRITE_MEASURING_MODE measuringMode;
-};
-
-/// <summary>
-/// The DWRITE_LINE_METRICS structure contains information about a formatted
-/// line of text.
-/// </summary>
-struct DWRITE_LINE_METRICS
-{
- /// <summary>
- /// The number of total text positions in the line.
- /// This includes any trailing whitespace and newline characters.
- /// </summary>
- UINT32 length;
-
- /// <summary>
- /// The number of whitespace positions at the end of the line. Newline
- /// sequences are considered whitespace.
- /// </summary>
- UINT32 trailingWhitespaceLength;
-
- /// <summary>
- /// The number of characters in the newline sequence at the end of the line.
- /// If the count is zero, then the line was either wrapped or it is the
- /// end of the text.
- /// </summary>
- UINT32 newlineLength;
-
- /// <summary>
- /// Height of the line as measured from top to bottom.
- /// </summary>
- FLOAT height;
-
- /// <summary>
- /// Distance from the top of the line to its baseline.
- /// </summary>
- FLOAT baseline;
-
- /// <summary>
- /// The line is trimmed.
- /// </summary>
- BOOL isTrimmed;
-};
-
-
-/// <summary>
-/// The DWRITE_CLUSTER_METRICS structure contains information about a glyph cluster.
-/// </summary>
-struct DWRITE_CLUSTER_METRICS
-{
- /// <summary>
- /// The total advance width of all glyphs in the cluster.
- /// </summary>
- FLOAT width;
-
- /// <summary>
- /// The number of text positions in the cluster.
- /// </summary>
- UINT16 length;
-
- /// <summary>
- /// Indicate whether line can be broken right after the cluster.
- /// </summary>
- UINT16 canWrapLineAfter : 1;
-
- /// <summary>
- /// Indicate whether the cluster corresponds to whitespace character.
- /// </summary>
- UINT16 isWhitespace : 1;
-
- /// <summary>
- /// Indicate whether the cluster corresponds to a newline character.
- /// </summary>
- UINT16 isNewline : 1;
-
- /// <summary>
- /// Indicate whether the cluster corresponds to soft hyphen character.
- /// </summary>
- UINT16 isSoftHyphen : 1;
-
- /// <summary>
- /// Indicate whether the cluster is read from right to left.
- /// </summary>
- UINT16 isRightToLeft : 1;
-
- UINT16 padding : 11;
-};
-
-
-/// <summary>
-/// Overall metrics associated with text after layout.
-/// All coordinates are in device independent pixels (DIPs).
-/// </summary>
-struct DWRITE_TEXT_METRICS
-{
- /// <summary>
- /// Left-most point of formatted text relative to layout box
- /// (excluding any glyph overhang).
- /// </summary>
- FLOAT left;
-
- /// <summary>
- /// Top-most point of formatted text relative to layout box
- /// (excluding any glyph overhang).
- /// </summary>
- FLOAT top;
-
- /// <summary>
- /// The width of the formatted text ignoring trailing whitespace
- /// at the end of each line.
- /// </summary>
- FLOAT width;
-
- /// <summary>
- /// The width of the formatted text taking into account the
- /// trailing whitespace at the end of each line.
- /// </summary>
- FLOAT widthIncludingTrailingWhitespace;
-
- /// <summary>
- /// The height of the formatted text. The height of an empty string
- /// is determined by the size of the default font's line height.
- /// </summary>
- FLOAT height;
-
- /// <summary>
- /// Initial width given to the layout. Depending on whether the text
- /// was wrapped or not, it can be either larger or smaller than the
- /// text content width.
- /// </summary>
- FLOAT layoutWidth;
-
- /// <summary>
- /// Initial height given to the layout. Depending on the length of the
- /// text, it may be larger or smaller than the text content height.
- /// </summary>
- FLOAT layoutHeight;
-
- /// <summary>
- /// The maximum reordering count of any line of text, used
- /// to calculate the most number of hit-testing boxes needed.
- /// If the layout has no bidirectional text or no text at all,
- /// the minimum level is 1.
- /// </summary>
- UINT32 maxBidiReorderingDepth;
-
- /// <summary>
- /// Total number of lines.
- /// </summary>
- UINT32 lineCount;
-};
-
-
-/// <summary>
-/// Properties describing the geometric measurement of an
-/// application-defined inline object.
-/// </summary>
-struct DWRITE_INLINE_OBJECT_METRICS
-{
- /// <summary>
- /// Width of the inline object.
- /// </summary>
- FLOAT width;
-
- /// <summary>
- /// Height of the inline object as measured from top to bottom.
- /// </summary>
- FLOAT height;
-
- /// <summary>
- /// Distance from the top of the object to the baseline where it is lined up with the adjacent text.
- /// If the baseline is at the bottom, baseline simply equals height.
- /// </summary>
- FLOAT baseline;
-
- /// <summary>
- /// Flag indicating whether the object is to be placed upright or alongside the text baseline
- /// for vertical text.
- /// </summary>
- BOOL supportsSideways;
-};
-
-
-/// <summary>
-/// The DWRITE_OVERHANG_METRICS structure holds how much any visible pixels
-/// (in DIPs) overshoot each side of the layout or inline objects.
-/// </summary>
-/// <remarks>
-/// Positive overhangs indicate that the visible area extends outside the layout
-/// box or inline object, while negative values mean there is whitespace inside.
-/// The returned values are unaffected by rendering transforms or pixel snapping.
-/// Additionally, they may not exactly match final target's pixel bounds after
-/// applying grid fitting and hinting.
-/// </remarks>
-struct DWRITE_OVERHANG_METRICS
-{
- /// <summary>
- /// The distance from the left-most visible DIP to its left alignment edge.
- /// </summary>
- FLOAT left;
-
- /// <summary>
- /// The distance from the top-most visible DIP to its top alignment edge.
- /// </summary>
- FLOAT top;
-
- /// <summary>
- /// The distance from the right-most visible DIP to its right alignment edge.
- /// </summary>
- FLOAT right;
-
- /// <summary>
- /// The distance from the bottom-most visible DIP to its bottom alignment edge.
- /// </summary>
- FLOAT bottom;
-};
-
-
-/// <summary>
-/// Geometry enclosing of text positions.
-/// </summary>
-struct DWRITE_HIT_TEST_METRICS
-{
- /// <summary>
- /// First text position within the geometry.
- /// </summary>
- UINT32 textPosition;
-
- /// <summary>
- /// Number of text positions within the geometry.
- /// </summary>
- UINT32 length;
-
- /// <summary>
- /// Left position of the top-left coordinate of the geometry.
- /// </summary>
- FLOAT left;
-
- /// <summary>
- /// Top position of the top-left coordinate of the geometry.
- /// </summary>
- FLOAT top;
-
- /// <summary>
- /// Geometry's width.
- /// </summary>
- FLOAT width;
-
- /// <summary>
- /// Geometry's height.
- /// </summary>
- FLOAT height;
-
- /// <summary>
- /// Bidi level of text positions enclosed within the geometry.
- /// </summary>
- UINT32 bidiLevel;
-
- /// <summary>
- /// Geometry encloses text?
- /// </summary>
- BOOL isText;
-
- /// <summary>
- /// Range is trimmed.
- /// </summary>
- BOOL isTrimmed;
-};
-
-
-interface IDWriteTextRenderer;
-
-
-/// <summary>
-/// The IDWriteInlineObject interface wraps an application defined inline graphic,
-/// allowing DWrite to query metrics as if it was a glyph inline with the text.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("8339FDE3-106F-47ab-8373-1C6295EB10B3") IDWriteInlineObject : public IUnknown
-{
- /// <summary>
- /// The application implemented rendering callback (IDWriteTextRenderer::DrawInlineObject)
- /// can use this to draw the inline object without needing to cast or query the object
- /// type. The text layout does not call this method directly.
- /// </summary>
- /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
- /// <param name="renderer">The renderer passed to IDWriteTextLayout::Draw as the object's containing parent.</param>
- /// <param name="originX">X-coordinate at the top-left corner of the inline object.</param>
- /// <param name="originY">Y-coordinate at the top-left corner of the inline object.</param>
- /// <param name="isSideways">The object should be drawn on its side.</param>
- /// <param name="isRightToLeft">The object is in an right-to-left context and should be drawn flipped.</param>
- /// <param name="clientDrawingEffect">The drawing effect set in IDWriteTextLayout::SetDrawingEffect.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(Draw)(
- __maybenull void* clientDrawingContext,
- IDWriteTextRenderer* renderer,
- FLOAT originX,
- FLOAT originY,
- BOOL isSideways,
- BOOL isRightToLeft,
- __maybenull IUnknown* clientDrawingEffect
- ) PURE;
-
- /// <summary>
- /// TextLayout calls this callback function to get the measurement of the inline object.
- /// </summary>
- /// <param name="metrics">Returned metrics</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetMetrics)(
- __out DWRITE_INLINE_OBJECT_METRICS* metrics
- ) PURE;
-
- /// <summary>
- /// TextLayout calls this callback function to get the visible extents (in DIPs) of the inline object.
- /// In the case of a simple bitmap, with no padding and no overhang, all the overhangs will
- /// simply be zeroes.
- /// </summary>
- /// <param name="overhangs">Overshoot of visible extents (in DIPs) outside the object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// The overhangs should be returned relative to the reported size of the object
- /// (DWRITE_INLINE_OBJECT_METRICS::width/height), and should not be baseline
- /// adjusted. If you have an image that is actually 100x100 DIPs, but you want it
- /// slightly inset (perhaps it has a glow) by 20 DIPs on each side, you would
- /// return a width/height of 60x60 and four overhangs of 20 DIPs.
- /// </remarks>
- STDMETHOD(GetOverhangMetrics)(
- __out DWRITE_OVERHANG_METRICS* overhangs
- ) PURE;
-
- /// <summary>
- /// Layout uses this to determine the line breaking behavior of the inline object
- /// amidst the text.
- /// </summary>
- /// <param name="breakConditionBefore">Line-breaking condition between the object and the content immediately preceding it.</param>
- /// <param name="breakConditionAfter" >Line-breaking condition between the object and the content immediately following it.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetBreakConditions)(
- __out DWRITE_BREAK_CONDITION* breakConditionBefore,
- __out DWRITE_BREAK_CONDITION* breakConditionAfter
- ) PURE;
-};
-
-/// <summary>
-/// The IDWritePixelSnapping interface defines the pixel snapping properties of a text renderer.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("eaf3a2da-ecf4-4d24-b644-b34f6842024b") IDWritePixelSnapping : public IUnknown
-{
- /// <summary>
- /// Determines whether pixel snapping is disabled. The recommended default is FALSE,
- /// unless doing animation that requires subpixel vertical placement.
- /// </summary>
- /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
- /// <param name="isDisabled">Receives TRUE if pixel snapping is disabled or FALSE if it not.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(IsPixelSnappingDisabled)(
- __maybenull void* clientDrawingContext,
- __out BOOL* isDisabled
- ) PURE;
-
- /// <summary>
- /// Gets the current transform that maps abstract coordinates to DIPs,
- /// which may disable pixel snapping upon any rotation or shear.
- /// </summary>
- /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
- /// <param name="transform">Receives the transform.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetCurrentTransform)(
- __maybenull void* clientDrawingContext,
- __out DWRITE_MATRIX* transform
- ) PURE;
-
- /// <summary>
- /// Gets the number of physical pixels per DIP. A DIP (device-independent pixel) is 1/96 inch,
- /// so the pixelsPerDip value is the number of logical pixels per inch divided by 96 (yielding
- /// a value of 1 for 96 DPI and 1.25 for 120).
- /// </summary>
- /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
- /// <param name="pixelsPerDip">Receives the number of physical pixels per DIP.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetPixelsPerDip)(
- __maybenull void* clientDrawingContext,
- __out FLOAT* pixelsPerDip
- ) PURE;
-};
-
-/// <summary>
-/// The IDWriteTextLayout interface represents a set of application-defined
-/// callbacks that perform rendering of text, inline objects, and decorations
-/// such as underlines.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("ef8a8135-5cc6-45fe-8825-c5a0724eb819") IDWriteTextRenderer : public IDWritePixelSnapping
-{
- /// <summary>
- /// IDWriteTextLayout::Draw calls this function to instruct the client to
- /// render a run of glyphs.
- /// </summary>
- /// <param name="clientDrawingContext">The context passed to
- /// IDWriteTextLayout::Draw.</param>
- /// <param name="baselineOriginX">X-coordinate of the baseline.</param>
- /// <param name="baselineOriginY">Y-coordinate of the baseline.</param>
- /// <param name="measuringMode">Specifies measuring method for glyphs in the run.
- /// Renderer implementations may choose different rendering modes for given measuring methods,
- /// but best results are seen when the rendering mode matches the corresponding measuring mode:
- /// DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL for DWRITE_MEASURING_MODE_NATURAL
- /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC for DWRITE_MEASURING_MODE_GDI_CLASSIC
- /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL for DWRITE_MEASURING_MODE_GDI_NATURAL
- /// </param>
- /// <param name="glyphRun">The glyph run to draw.</param>
- /// <param name="glyphRunDescription">Properties of the characters
- /// associated with this run.</param>
- /// <param name="clientDrawingEffect">The drawing effect set in
- /// IDWriteTextLayout::SetDrawingEffect.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(DrawGlyphRun)(
- __maybenull void* clientDrawingContext,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- DWRITE_MEASURING_MODE measuringMode,
- __in DWRITE_GLYPH_RUN const* glyphRun,
- __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
- __maybenull IUnknown* clientDrawingEffect
- ) PURE;
-
- /// <summary>
- /// IDWriteTextLayout::Draw calls this function to instruct the client to draw
- /// an underline.
- /// </summary>
- /// <param name="clientDrawingContext">The context passed to
- /// IDWriteTextLayout::Draw.</param>
- /// <param name="baselineOriginX">X-coordinate of the baseline.</param>
- /// <param name="baselineOriginY">Y-coordinate of the baseline.</param>
- /// <param name="underline">Underline logical information.</param>
- /// <param name="clientDrawingEffect">The drawing effect set in
- /// IDWriteTextLayout::SetDrawingEffect.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// A single underline can be broken into multiple calls, depending on
- /// how the formatting changes attributes. If font sizes/styles change
- /// within an underline, the thickness and offset will be averaged
- /// weighted according to characters.
- /// To get the correct top coordinate of the underline rect, add underline::offset
- /// to the baseline's Y. Otherwise the underline will be immediately under the text.
- /// The x coordinate will always be passed as the left side, regardless
- /// of text directionality. This simplifies drawing and reduces the
- /// problem of round-off that could potentially cause gaps or a double
- /// stamped alpha blend. To avoid alpha overlap, round the end points
- /// to the nearest device pixel.
- /// </remarks>
- STDMETHOD(DrawUnderline)(
- __maybenull void* clientDrawingContext,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- __in DWRITE_UNDERLINE const* underline,
- __maybenull IUnknown* clientDrawingEffect
- ) PURE;
-
- /// <summary>
- /// IDWriteTextLayout::Draw calls this function to instruct the client to draw
- /// a strikethrough.
- /// </summary>
- /// <param name="clientDrawingContext">The context passed to
- /// IDWriteTextLayout::Draw.</param>
- /// <param name="baselineOriginX">X-coordinate of the baseline.</param>
- /// <param name="baselineOriginY">Y-coordinate of the baseline.</param>
- /// <param name="strikethrough">Strikethrough logical information.</param>
- /// <param name="clientDrawingEffect">The drawing effect set in
- /// IDWriteTextLayout::SetDrawingEffect.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// A single strikethrough can be broken into multiple calls, depending on
- /// how the formatting changes attributes. Strikethrough is not averaged
- /// across font sizes/styles changes.
- /// To get the correct top coordinate of the strikethrough rect,
- /// add strikethrough::offset to the baseline's Y.
- /// Like underlines, the x coordinate will always be passed as the left side,
- /// regardless of text directionality.
- /// </remarks>
- STDMETHOD(DrawStrikethrough)(
- __maybenull void* clientDrawingContext,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- __in DWRITE_STRIKETHROUGH const* strikethrough,
- __maybenull IUnknown* clientDrawingEffect
- ) PURE;
-
- /// <summary>
- /// IDWriteTextLayout::Draw calls this application callback when it needs to
- /// draw an inline object.
- /// </summary>
- /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
- /// <param name="originX">X-coordinate at the top-left corner of the inline object.</param>
- /// <param name="originY">Y-coordinate at the top-left corner of the inline object.</param>
- /// <param name="inlineObject">The object set using IDWriteTextLayout::SetInlineObject.</param>
- /// <param name="isSideways">The object should be drawn on its side.</param>
- /// <param name="isRightToLeft">The object is in an right-to-left context and should be drawn flipped.</param>
- /// <param name="clientDrawingEffect">The drawing effect set in
- /// IDWriteTextLayout::SetDrawingEffect.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// The right-to-left flag is a hint for those cases where it would look
- /// strange for the image to be shown normally (like an arrow pointing to
- /// right to indicate a submenu).
- /// </remarks>
- STDMETHOD(DrawInlineObject)(
- __maybenull void* clientDrawingContext,
- FLOAT originX,
- FLOAT originY,
- IDWriteInlineObject* inlineObject,
- BOOL isSideways,
- BOOL isRightToLeft,
- __maybenull IUnknown* clientDrawingEffect
- ) PURE;
-};
-
-/// <summary>
-/// The IDWriteTextLayout interface represents a block of text after it has
-/// been fully analyzed and formatted.
-///
-/// All coordinates are in device independent pixels (DIPs).
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("53737037-6d14-410b-9bfe-0b182bb70961") IDWriteTextLayout : public IDWriteTextFormat
-{
- /// <summary>
- /// Set layout maximum width
- /// </summary>
- /// <param name="maxWidth">Layout maximum width</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetMaxWidth)(
- FLOAT maxWidth
- ) PURE;
-
- /// <summary>
- /// Set layout maximum height
- /// </summary>
- /// <param name="maxHeight">Layout maximum height</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetMaxHeight)(
- FLOAT maxHeight
- ) PURE;
-
- /// <summary>
- /// Set the font collection.
- /// </summary>
- /// <param name="fontCollection">The font collection to set</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetFontCollection)(
- IDWriteFontCollection* fontCollection,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set null-terminated font family name.
- /// </summary>
- /// <param name="fontFamilyName">Font family name</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetFontFamilyName)(
- __in_z WCHAR const* fontFamilyName,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set font weight.
- /// </summary>
- /// <param name="fontWeight">Font weight</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetFontWeight)(
- DWRITE_FONT_WEIGHT fontWeight,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set font style.
- /// </summary>
- /// <param name="fontStyle">Font style</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetFontStyle)(
- DWRITE_FONT_STYLE fontStyle,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set font stretch.
- /// </summary>
- /// <param name="fontStretch">font stretch</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetFontStretch)(
- DWRITE_FONT_STRETCH fontStretch,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set font em height.
- /// </summary>
- /// <param name="fontSize">Font em height</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetFontSize)(
- FLOAT fontSize,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set underline.
- /// </summary>
- /// <param name="hasUnderline">The Boolean flag indicates whether underline takes place</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetUnderline)(
- BOOL hasUnderline,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set strikethrough.
- /// </summary>
- /// <param name="hasStrikethrough">The Boolean flag indicates whether strikethrough takes place</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetStrikethrough)(
- BOOL hasStrikethrough,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set application-defined drawing effect.
- /// </summary>
- /// <param name="drawingEffect">Pointer to an application-defined drawing effect.</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// This drawing effect is associated with the specified range and will be passed back
- /// to the application via the callback when the range is drawn at drawing time.
- /// </remarks>
- STDMETHOD(SetDrawingEffect)(
- IUnknown* drawingEffect,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set inline object.
- /// </summary>
- /// <param name="inlineObject">Pointer to an application-implemented inline object.</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// This inline object applies to the specified range and will be passed back
- /// to the application via the DrawInlineObject callback when the range is drawn.
- /// Any text in that range will be suppressed.
- /// </remarks>
- STDMETHOD(SetInlineObject)(
- IDWriteInlineObject* inlineObject,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set font typography features.
- /// </summary>
- /// <param name="typography">Pointer to font typography setting.</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetTypography)(
- IDWriteTypography* typography,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Set locale name.
- /// </summary>
- /// <param name="localeName">Locale name</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetLocaleName)(
- __in_z WCHAR const* localeName,
- DWRITE_TEXT_RANGE textRange
- ) PURE;
-
- /// <summary>
- /// Get layout maximum width
- /// </summary>
- STDMETHOD_(FLOAT, GetMaxWidth)() PURE;
-
- /// <summary>
- /// Get layout maximum height
- /// </summary>
- STDMETHOD_(FLOAT, GetMaxHeight)() PURE;
-
- /// <summary>
- /// Get the font collection where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="fontCollection">The current font collection</param>
- /// <param name="textRange">Text range to which this change applies.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontCollection)(
- UINT32 currentPosition,
- __out IDWriteFontCollection** fontCollection,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the length of the font family name where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="nameLength">Size of the character array in character count not including the terminated NULL character.</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontFamilyNameLength)(
- UINT32 currentPosition,
- __out UINT32* nameLength,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Copy the font family name where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="fontFamilyName">Character array that receives the current font family name</param>
- /// <param name="nameSize">Size of the character array in character count including the terminated NULL character.</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontFamilyName)(
- UINT32 currentPosition,
- __out_ecount_z(nameSize) WCHAR* fontFamilyName,
- UINT32 nameSize,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the font weight where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="fontWeight">The current font weight</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontWeight)(
- UINT32 currentPosition,
- __out DWRITE_FONT_WEIGHT* fontWeight,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the font style where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="fontStyle">The current font style</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontStyle)(
- UINT32 currentPosition,
- __out DWRITE_FONT_STYLE* fontStyle,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the font stretch where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="fontStretch">The current font stretch</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontStretch)(
- UINT32 currentPosition,
- __out DWRITE_FONT_STRETCH* fontStretch,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the font em height where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="fontSize">The current font em height</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetFontSize)(
- UINT32 currentPosition,
- __out FLOAT* fontSize,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the underline presence where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="hasUnderline">The Boolean flag indicates whether text is underlined.</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetUnderline)(
- UINT32 currentPosition,
- __out BOOL* hasUnderline,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the strikethrough presence where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="hasStrikethrough">The Boolean flag indicates whether text has strikethrough.</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetStrikethrough)(
- UINT32 currentPosition,
- __out BOOL* hasStrikethrough,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the application-defined drawing effect where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="drawingEffect">The current application-defined drawing effect.</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetDrawingEffect)(
- UINT32 currentPosition,
- __out IUnknown** drawingEffect,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the inline object at the given position.
- /// </summary>
- /// <param name="currentPosition">The given text position.</param>
- /// <param name="inlineObject">The inline object.</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetInlineObject)(
- UINT32 currentPosition,
- __out IDWriteInlineObject** inlineObject,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the typography setting where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="typography">The current typography setting.</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetTypography)(
- UINT32 currentPosition,
- __out IDWriteTypography** typography,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the length of the locale name where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="nameLength">Size of the character array in character count not including the terminated NULL character.</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetLocaleNameLength)(
- UINT32 currentPosition,
- __out UINT32* nameLength,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Get the locale name where the current position is at.
- /// </summary>
- /// <param name="currentPosition">The current text position.</param>
- /// <param name="localeName">Character array that receives the current locale name</param>
- /// <param name="nameSize">Size of the character array in character count including the terminated NULL character.</param>
- /// <param name="textRange">The position range of the current format.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetLocaleName)(
- UINT32 currentPosition,
- __out_ecount_z(nameSize) WCHAR* localeName,
- UINT32 nameSize,
- __out_opt DWRITE_TEXT_RANGE* textRange = NULL
- ) PURE;
-
- /// <summary>
- /// Initiate drawing of the text.
- /// </summary>
- /// <param name="clientDrawingContext">An application defined value
- /// included in rendering callbacks.</param>
- /// <param name="renderer">The set of application-defined callbacks that do
- /// the actual rendering.</param>
- /// <param name="originX">X-coordinate of the layout's left side.</param>
- /// <param name="originY">Y-coordinate of the layout's top side.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(Draw)(
- __maybenull void* clientDrawingContext,
- IDWriteTextRenderer* renderer,
- FLOAT originX,
- FLOAT originY
- ) PURE;
-
- /// <summary>
- /// GetLineMetrics returns properties of each line.
- /// </summary>
- /// <param name="lineMetrics">The array to fill with line information.</param>
- /// <param name="maxLineCount">The maximum size of the lineMetrics array.</param>
- /// <param name="actualLineCount">The actual size of the lineMetrics
- /// array that is needed.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// If maxLineCount is not large enough E_NOT_SUFFICIENT_BUFFER,
- /// which is equivalent to HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
- /// is returned and *actualLineCount is set to the number of lines
- /// needed.
- /// </remarks>
- STDMETHOD(GetLineMetrics)(
- __out_ecount_opt(maxLineCount) DWRITE_LINE_METRICS* lineMetrics,
- UINT32 maxLineCount,
- __out UINT32* actualLineCount
- ) PURE;
-
- /// <summary>
- /// GetMetrics retrieves overall metrics for the formatted string.
- /// </summary>
- /// <param name="textMetrics">The returned metrics.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// Drawing effects like underline and strikethrough do not contribute
- /// to the text size, which is essentially the sum of advance widths and
- /// line heights. Additionally, visible swashes and other graphic
- /// adornments may extend outside the returned width and height.
- /// </remarks>
- STDMETHOD(GetMetrics)(
- __out DWRITE_TEXT_METRICS* textMetrics
- ) PURE;
-
- /// <summary>
- /// GetOverhangMetrics returns the overhangs (in DIPs) of the layout and all
- /// objects contained in it, including text glyphs and inline objects.
- /// </summary>
- /// <param name="overhangs">Overshoots of visible extents (in DIPs) outside the layout.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// Any underline and strikethrough do not contribute to the black box
- /// determination, since these are actually drawn by the renderer, which
- /// is allowed to draw them in any variety of styles.
- /// </remarks>
- STDMETHOD(GetOverhangMetrics)(
- __out DWRITE_OVERHANG_METRICS* overhangs
- ) PURE;
-
- /// <summary>
- /// Retrieve logical properties and measurement of each cluster.
- /// </summary>
- /// <param name="clusterMetrics">The array to fill with cluster information.</param>
- /// <param name="maxClusterCount">The maximum size of the clusterMetrics array.</param>
- /// <param name="actualClusterCount">The actual size of the clusterMetrics array that is needed.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// If maxClusterCount is not large enough E_NOT_SUFFICIENT_BUFFER,
- /// which is equivalent to HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
- /// is returned and *actualClusterCount is set to the number of clusters
- /// needed.
- /// </remarks>
- STDMETHOD(GetClusterMetrics)(
- __out_ecount_opt(maxClusterCount) DWRITE_CLUSTER_METRICS* clusterMetrics,
- UINT32 maxClusterCount,
- __out UINT32* actualClusterCount
- ) PURE;
-
- /// <summary>
- /// Determines the minimum possible width the layout can be set to without
- /// emergency breaking between the characters of whole words.
- /// </summary>
- /// <param name="minWidth">Minimum width.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(DetermineMinWidth)(
- __out FLOAT* minWidth
- ) PURE;
-
- /// <summary>
- /// Given a coordinate (in DIPs) relative to the top-left of the layout box,
- /// this returns the corresponding hit-test metrics of the text string where
- /// the hit-test has occurred. This is useful for mapping mouse clicks to caret
- /// positions. When the given coordinate is outside the text string, the function
- /// sets the output value *isInside to false but returns the nearest character
- /// position.
- /// </summary>
- /// <param name="pointX">X coordinate to hit-test, relative to the top-left location of the layout box.</param>
- /// <param name="pointY">Y coordinate to hit-test, relative to the top-left location of the layout box.</param>
- /// <param name="isTrailingHit">Output flag indicating whether the hit-test location is at the leading or the trailing
- /// side of the character. When the output *isInside value is set to false, this value is set according to the output
- /// *position value to represent the edge closest to the hit-test location. </param>
- /// <param name="isInside">Output flag indicating whether the hit-test location is inside the text string.
- /// When false, the position nearest the text's edge is returned.</param>
- /// <param name="hitTestMetrics">Output geometry fully enclosing the hit-test location. When the output *isInside value
- /// is set to false, this structure represents the geometry enclosing the edge closest to the hit-test location.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(HitTestPoint)(
- FLOAT pointX,
- FLOAT pointY,
- __out BOOL* isTrailingHit,
- __out BOOL* isInside,
- __out DWRITE_HIT_TEST_METRICS* hitTestMetrics
- ) PURE;
-
- /// <summary>
- /// Given a text position and whether the caret is on the leading or trailing
- /// edge of that position, this returns the corresponding coordinate (in DIPs)
- /// relative to the top-left of the layout box. This is most useful for drawing
- /// the caret's current position, but it could also be used to anchor an IME to the
- /// typed text or attach a floating menu near the point of interest. It may also be
- /// used to programmatically obtain the geometry of a particular text position
- /// for UI automation.
- /// </summary>
- /// <param name="textPosition">Text position to get the coordinate of.</param>
- /// <param name="isTrailingHit">Flag indicating whether the location is of the leading or the trailing side of the specified text position. </param>
- /// <param name="pointX">Output caret X, relative to the top-left of the layout box.</param>
- /// <param name="pointY">Output caret Y, relative to the top-left of the layout box.</param>
- /// <param name="hitTestMetrics">Output geometry fully enclosing the specified text position.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// When drawing a caret at the returned X,Y, it should should be centered on X
- /// and drawn from the Y coordinate down. The height will be the size of the
- /// hit-tested text (which can vary in size within a line).
- /// Reading direction also affects which side of the character the caret is drawn.
- /// However, the returned X coordinate will be correct for either case.
- /// You can get a text length back that is larger than a single character.
- /// This happens for complex scripts when multiple characters form a single cluster,
- /// when diacritics join their base character, or when you test a surrogate pair.
- /// </remarks>
- STDMETHOD(HitTestTextPosition)(
- UINT32 textPosition,
- BOOL isTrailingHit,
- __out FLOAT* pointX,
- __out FLOAT* pointY,
- __out DWRITE_HIT_TEST_METRICS* hitTestMetrics
- ) PURE;
-
- /// <summary>
- /// The application calls this function to get a set of hit-test metrics
- /// corresponding to a range of text positions. The main usage for this
- /// is to draw highlighted selection of the text string.
- ///
- /// The function returns E_NOT_SUFFICIENT_BUFFER, which is equivalent to
- /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), when the buffer size of
- /// hitTestMetrics is too small to hold all the regions calculated by the
- /// function. In such situation, the function sets the output value
- /// *actualHitTestMetricsCount to the number of geometries calculated.
- /// The application is responsible to allocate a new buffer of greater
- /// size and call the function again.
- ///
- /// A good value to use as an initial value for maxHitTestMetricsCount may
- /// be calculated from the following equation:
- /// maxHitTestMetricsCount = lineCount * maxBidiReorderingDepth
- ///
- /// where lineCount is obtained from the value of the output argument
- /// *actualLineCount from the function IDWriteTextLayout::GetLineMetrics,
- /// and the maxBidiReorderingDepth value from the DWRITE_TEXT_METRICS
- /// structure of the output argument *textMetrics from the function
- /// IDWriteFactory::CreateTextLayout.
- /// </summary>
- /// <param name="textPosition">First text position of the specified range.</param>
- /// <param name="textLength">Number of positions of the specified range.</param>
- /// <param name="originX">Offset of the X origin (left of the layout box) which is added to each of the hit-test metrics returned.</param>
- /// <param name="originY">Offset of the Y origin (top of the layout box) which is added to each of the hit-test metrics returned.</param>
- /// <param name="hitTestMetrics">Pointer to a buffer of the output geometry fully enclosing the specified position range.</param>
- /// <param name="maxHitTestMetricsCount">Maximum number of distinct metrics it could hold in its buffer memory.</param>
- /// <param name="actualHitTestMetricsCount">Actual number of metrics returned or needed.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// There are no gaps in the returned metrics. While there could be visual gaps,
- /// depending on bidi ordering, each range is contiguous and reports all the text,
- /// including any hidden characters and trimmed text.
- /// The height of each returned range will be the same within each line, regardless
- /// of how the font sizes vary.
- /// </remarks>
- STDMETHOD(HitTestTextRange)(
- UINT32 textPosition,
- UINT32 textLength,
- FLOAT originX,
- FLOAT originY,
- __out_ecount_opt(maxHitTestMetricsCount) DWRITE_HIT_TEST_METRICS* hitTestMetrics,
- UINT32 maxHitTestMetricsCount,
- __out UINT32* actualHitTestMetricsCount
- ) PURE;
-};
-
-/// <summary>
-/// Encapsulates a 32-bit device independent bitmap and device context, which can be used for rendering glyphs.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("5e5a32a3-8dff-4773-9ff6-0696eab77267") IDWriteBitmapRenderTarget : public IUnknown
-{
- /// <summary>
- /// Draws a run of glyphs to the bitmap.
- /// </summary>
- /// <param name="baselineOriginX">Horizontal position of the baseline origin, in DIPs, relative to the upper-left corner of the DIB.</param>
- /// <param name="baselineOriginY">Vertical position of the baseline origin, in DIPs, relative to the upper-left corner of the DIB.</param>
- /// <param name="measuringMode">Specifies measuring method for glyphs in the run.
- /// Renderer implementations may choose different rendering modes for different measuring methods, for example
- /// DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL for DWRITE_MEASURING_MODE_NATURAL,
- /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC for DWRITE_MEASURING_MODE_GDI_CLASSIC, and
- /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL for DWRITE_MEASURING_MODE_GDI_NATURAL.
- /// </param>
- /// <param name="glyphRun">Structure containing the properties of the glyph run.</param>
- /// <param name="renderingParams">Object that controls rendering behavior.</param>
- /// <param name="textColor">Specifies the foreground color of the text.</param>
- /// <param name="blackBoxRect">Optional rectangle that receives the bounding box (in pixels not DIPs) of all the pixels affected by
- /// drawing the glyph run. The black box rectangle may extend beyond the dimensions of the bitmap.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(DrawGlyphRun)(
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- DWRITE_MEASURING_MODE measuringMode,
- __in DWRITE_GLYPH_RUN const* glyphRun,
- IDWriteRenderingParams* renderingParams,
- COLORREF textColor,
- __out_opt RECT* blackBoxRect = NULL
- ) PURE;
-
- /// <summary>
- /// Gets a handle to the memory device context.
- /// </summary>
- /// <returns>
- /// Returns the device context handle.
- /// </returns>
- /// <remarks>
- /// An application can use the device context to draw using GDI functions. An application can obtain the bitmap handle
- /// (HBITMAP) by calling GetCurrentObject. An application that wants information about the underlying bitmap, including
- /// a pointer to the pixel data, can call GetObject to fill in a DIBSECTION structure. The bitmap is always a 32-bit
- /// top-down DIB.
- /// </remarks>
- STDMETHOD_(HDC, GetMemoryDC)() PURE;
-
- /// <summary>
- /// Gets the number of bitmap pixels per DIP. A DIP (device-independent pixel) is 1/96 inch so this value is the number
- /// if pixels per inch divided by 96.
- /// </summary>
- /// <returns>
- /// Returns the number of bitmap pixels per DIP.
- /// </returns>
- STDMETHOD_(FLOAT, GetPixelsPerDip)() PURE;
-
- /// <summary>
- /// Sets the number of bitmap pixels per DIP. A DIP (device-independent pixel) is 1/96 inch so this value is the number
- /// if pixels per inch divided by 96.
- /// </summary>
- /// <param name="pixelsPerDip">Specifies the number of pixels per DIP.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetPixelsPerDip)(
- FLOAT pixelsPerDip
- ) PURE;
-
- /// <summary>
- /// Gets the transform that maps abstract coordinate to DIPs. By default this is the identity
- /// transform. Note that this is unrelated to the world transform of the underlying device
- /// context.
- /// </summary>
- /// <param name="transform">Receives the transform.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetCurrentTransform)(
- __out DWRITE_MATRIX* transform
- ) PURE;
-
- /// <summary>
- /// Sets the transform that maps abstract coordinate to DIPs. This does not affect the world
- /// transform of the underlying device context.
- /// </summary>
- /// <param name="transform">Specifies the new transform. This parameter can be NULL, in which
- /// case the identity transform is implied.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(SetCurrentTransform)(
- __in_opt DWRITE_MATRIX const* transform
- ) PURE;
-
- /// <summary>
- /// Gets the dimensions of the bitmap.
- /// </summary>
- /// <param name="size">Receives the size of the bitmap in pixels.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetSize)(
- __out SIZE* size
- ) PURE;
-
- /// <summary>
- /// Resizes the bitmap.
- /// </summary>
- /// <param name="width">New bitmap width, in pixels.</param>
- /// <param name="height">New bitmap height, in pixels.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(Resize)(
- UINT32 width,
- UINT32 height
- ) PURE;
-};
-
-/// <summary>
-/// The GDI interop interface provides interoperability with GDI.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("1edd9491-9853-4299-898f-6432983b6f3a") IDWriteGdiInterop : public IUnknown
-{
- /// <summary>
- /// Creates a font object that matches the properties specified by the LOGFONT structure.
- /// </summary>
- /// <param name="logFont">Structure containing a GDI-compatible font description.</param>
- /// <param name="font">Receives a newly created font object if successful, or NULL in case of error.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateFontFromLOGFONT)(
- __in LOGFONTW const* logFont,
- __out IDWriteFont** font
- ) PURE;
-
- /// <summary>
- /// Initializes a LOGFONT structure based on the GDI-compatible properties of the specified font.
- /// </summary>
- /// <param name="font">Specifies a font in the system font collection.</param>
- /// <param name="logFont">Structure that receives a GDI-compatible font description.</param>
- /// <param name="isSystemFont">Contains TRUE if the specified font object is part of the system font collection
- /// or FALSE otherwise.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(ConvertFontToLOGFONT)(
- IDWriteFont* font,
- __out LOGFONTW* logFont,
- __out BOOL* isSystemFont
- ) PURE;
-
- /// <summary>
- /// Initializes a LOGFONT structure based on the GDI-compatible properties of the specified font.
- /// </summary>
- /// <param name="font">Specifies a font face.</param>
- /// <param name="logFont">Structure that receives a GDI-compatible font description.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(ConvertFontFaceToLOGFONT)(
- IDWriteFontFace* font,
- __out LOGFONTW* logFont
- ) PURE;
-
- /// <summary>
- /// Creates a font face object that corresponds to the currently selected HFONT.
- /// </summary>
- /// <param name="hdc">Handle to a device context into which a font has been selected. It is assumed that the client
- /// has already performed font mapping and that the font selected into the DC is the actual font that would be used
- /// for rendering glyphs.</param>
- /// <param name="fontFace">Contains the newly created font face object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateFontFaceFromHdc)(
- HDC hdc,
- __out IDWriteFontFace** fontFace
- ) PURE;
-
- /// <summary>
- /// Creates an object that encapsulates a bitmap and memory DC which can be used for rendering glyphs.
- /// </summary>
- /// <param name="hdc">Optional device context used to create a compatible memory DC.</param>
- /// <param name="width">Width of the bitmap.</param>
- /// <param name="height">Height of the bitmap.</param>
- /// <param name="renderTarget">Receives a pointer to the newly created render target.</param>
- STDMETHOD(CreateBitmapRenderTarget)(
- __in_opt HDC hdc,
- UINT32 width,
- UINT32 height,
- __out IDWriteBitmapRenderTarget** renderTarget
- ) PURE;
-};
-
-/// <summary>
-/// The DWRITE_TEXTURE_TYPE enumeration identifies a type of alpha texture. An alpha texture is a bitmap of alpha values, each
-/// representing the darkness (i.e., opacity) of a pixel or subpixel.
-/// </summary>
-enum DWRITE_TEXTURE_TYPE
-{
- /// <summary>
- /// Specifies an alpha texture for aliased text rendering (i.e., bi-level, where each pixel is either fully opaque or fully transparent),
- /// with one byte per pixel.
- /// </summary>
- DWRITE_TEXTURE_ALIASED_1x1,
-
- /// <summary>
- /// Specifies an alpha texture for ClearType text rendering, with three bytes per pixel in the horizontal dimension and
- /// one byte per pixel in the vertical dimension.
- /// </summary>
- DWRITE_TEXTURE_CLEARTYPE_3x1
-};
-
-/// <summary>
-/// Maximum alpha value in a texture returned by IDWriteGlyphRunAnalysis::CreateAlphaTexture.
-/// </summary>
-#define DWRITE_ALPHA_MAX 255
-
-/// <summary>
-/// Interface that encapsulates information used to render a glyph run.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("7d97dbf7-e085-42d4-81e3-6a883bded118") IDWriteGlyphRunAnalysis : public IUnknown
-{
- /// <summary>
- /// Gets the bounding rectangle of the physical pixels affected by the glyph run.
- /// </summary>
- /// <param name="textureType">Specifies the type of texture requested. If a bi-level texture is requested, the
- /// bounding rectangle includes only bi-level glyphs. Otherwise, the bounding rectangle includes only anti-aliased
- /// glyphs.</param>
- /// <param name="textureBounds">Receives the bounding rectangle, or an empty rectangle if there are no glyphs
- /// if the specified type.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetAlphaTextureBounds)(
- DWRITE_TEXTURE_TYPE textureType,
- __out RECT* textureBounds
- ) PURE;
-
- /// <summary>
- /// Creates an alpha texture of the specified type.
- /// </summary>
- /// <param name="textureType">Specifies the type of texture requested. If a bi-level texture is requested, the
- /// texture contains only bi-level glyphs. Otherwise, the texture contains only anti-aliased glyphs.</param>
- /// <param name="textureBounds">Specifies the bounding rectangle of the texture, which can be different than
- /// the bounding rectangle returned by GetAlphaTextureBounds.</param>
- /// <param name="alphaValues">Receives the array of alpha values.</param>
- /// <param name="bufferSize">Size of the alphaValues array. The minimum size depends on the dimensions of the
- /// rectangle and the type of texture requested.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateAlphaTexture)(
- DWRITE_TEXTURE_TYPE textureType,
- __in RECT const* textureBounds,
- __out_bcount(bufferSize) BYTE* alphaValues,
- UINT32 bufferSize
- ) PURE;
-
- /// <summary>
- /// Gets properties required for ClearType blending.
- /// </summary>
- /// <param name="renderingParams">Rendering parameters object. In most cases, the values returned in the output
- /// parameters are based on the properties of this object. The exception is if a GDI-compatible rendering mode
- /// is specified.</param>
- /// <param name="blendGamma">Receives the gamma value to use for gamma correction.</param>
- /// <param name="blendEnhancedContrast">Receives the enhanced contrast value.</param>
- /// <param name="blendClearTypeLevel">Receives the ClearType level.</param>
- STDMETHOD(GetAlphaBlendParams)(
- IDWriteRenderingParams* renderingParams,
- __out FLOAT* blendGamma,
- __out FLOAT* blendEnhancedContrast,
- __out FLOAT* blendClearTypeLevel
- ) PURE;
-};
-
-/// <summary>
-/// The root factory interface for all DWrite objects.
-/// </summary>
-interface DWRITE_DECLARE_INTERFACE("b859ee5a-d838-4b5b-a2e8-1adc7d93db48") IDWriteFactory : public IUnknown
-{
- /// <summary>
- /// Gets a font collection representing the set of installed fonts.
- /// </summary>
- /// <param name="fontCollection">Receives a pointer to the system font collection object, or NULL in case of failure.</param>
- /// <param name="checkForUpdates">If this parameter is nonzero, the function performs an immediate check for changes to the set of
- /// installed fonts. If this parameter is FALSE, the function will still detect changes if the font cache service is running, but
- /// there may be some latency. For example, an application might specify TRUE if it has itself just installed a font and wants to
- /// be sure the font collection contains that font.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetSystemFontCollection)(
- __out IDWriteFontCollection** fontCollection,
- BOOL checkForUpdates = FALSE
- ) PURE;
-
- /// <summary>
- /// Creates a font collection using a custom font collection loader.
- /// </summary>
- /// <param name="collectionLoader">Application-defined font collection loader, which must have been previously
- /// registered using RegisterFontCollectionLoader.</param>
- /// <param name="collectionKey">Key used by the loader to identify a collection of font files.</param>
- /// <param name="collectionKeySize">Size in bytes of the collection key.</param>
- /// <param name="fontCollection">Receives a pointer to the system font collection object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateCustomFontCollection)(
- IDWriteFontCollectionLoader* collectionLoader,
- __in_bcount(collectionKeySize) void const* collectionKey,
- UINT32 collectionKeySize,
- __out IDWriteFontCollection** fontCollection
- ) PURE;
-
- /// <summary>
- /// Registers a custom font collection loader with the factory object.
- /// </summary>
- /// <param name="fontCollectionLoader">Application-defined font collection loader.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(RegisterFontCollectionLoader)(
- IDWriteFontCollectionLoader* fontCollectionLoader
- ) PURE;
-
- /// <summary>
- /// Unregisters a custom font collection loader that was previously registered using RegisterFontCollectionLoader.
- /// </summary>
- /// <param name="fontCollectionLoader">Application-defined font collection loader.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(UnregisterFontCollectionLoader)(
- IDWriteFontCollectionLoader* fontCollectionLoader
- ) PURE;
-
- /// <summary>
- /// CreateFontFileReference creates a font file reference object from a local font file.
- /// </summary>
- /// <param name="filePath">Absolute file path. Subsequent operations on the constructed object may fail
- /// if the user provided filePath doesn't correspond to a valid file on the disk.</param>
- /// <param name="lastWriteTime">Last modified time of the input file path. If the parameter is omitted,
- /// the function will access the font file to obtain its last write time, so the clients are encouraged to specify this value
- /// to avoid extra disk access. Subsequent operations on the constructed object may fail
- /// if the user provided lastWriteTime doesn't match the file on the disk.</param>
- /// <param name="fontFile">Contains newly created font file reference object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateFontFileReference)(
- __in_z WCHAR const* filePath,
- __in_opt FILETIME const* lastWriteTime,
- __out IDWriteFontFile** fontFile
- ) PURE;
-
- /// <summary>
- /// CreateCustomFontFileReference creates a reference to an application specific font file resource.
- /// This function enables an application or a document to use a font without having to install it on the system.
- /// The fontFileReferenceKey has to be unique only in the scope of the fontFileLoader used in this call.
- /// </summary>
- /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the font file resource
- /// during the lifetime of fontFileLoader.</param>
- /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
- /// <param name="fontFileLoader">Font file loader that will be used by the font system to load data from the file identified by
- /// fontFileReferenceKey.</param>
- /// <param name="fontFile">Contains the newly created font file object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// This function is provided for cases when an application or a document needs to use a font
- /// without having to install it on the system. fontFileReferenceKey has to be unique only in the scope
- /// of the fontFileLoader used in this call.
- /// </remarks>
- STDMETHOD(CreateCustomFontFileReference)(
- __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- IDWriteFontFileLoader* fontFileLoader,
- __out IDWriteFontFile** fontFile
- ) PURE;
-
- /// <summary>
- /// Creates a font face object.
- /// </summary>
- /// <param name="fontFaceType">The file format of the font face.</param>
- /// <param name="numberOfFiles">The number of font files require to represent the font face.</param>
- /// <param name="fontFiles">Font files representing the font face. Since IDWriteFontFace maintains its own references
- /// to the input font file objects, it's OK to release them after this call.</param>
- /// <param name="faceIndex">The zero based index of a font face in cases when the font files contain a collection of font faces.
- /// If the font files contain a single face, this value should be zero.</param>
- /// <param name="fontFaceSimulationFlags">Font face simulation flags for algorithmic emboldening and italicization.</param>
- /// <param name="fontFace">Contains the newly created font face object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateFontFace)(
- DWRITE_FONT_FACE_TYPE fontFaceType,
- UINT32 numberOfFiles,
- __in_ecount(numberOfFiles) IDWriteFontFile* const* fontFiles,
- UINT32 faceIndex,
- DWRITE_FONT_SIMULATIONS fontFaceSimulationFlags,
- __out IDWriteFontFace** fontFace
- ) PURE;
-
- /// <summary>
- /// Creates a rendering parameters object with default settings for the primary monitor.
- /// </summary>
- /// <param name="renderingParams">Holds the newly created rendering parameters object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateRenderingParams)(
- __out IDWriteRenderingParams** renderingParams
- ) PURE;
-
- /// <summary>
- /// Creates a rendering parameters object with default settings for the specified monitor.
- /// </summary>
- /// <param name="monitor">The monitor to read the default values from.</param>
- /// <param name="renderingParams">Holds the newly created rendering parameters object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateMonitorRenderingParams)(
- HMONITOR monitor,
- __out IDWriteRenderingParams** renderingParams
- ) PURE;
-
- /// <summary>
- /// Creates a rendering parameters object with the specified properties.
- /// </summary>
- /// <param name="gamma">The gamma value used for gamma correction, which must be greater than zero and cannot exceed 256.</param>
- /// <param name="enhancedContrast">The amount of contrast enhancement, zero or greater.</param>
- /// <param name="clearTypeLevel">The degree of ClearType level, from 0.0f (no ClearType) to 1.0f (full ClearType).</param>
- /// <param name="pixelGeometry">The geometry of a device pixel.</param>
- /// <param name="renderingMode">Method of rendering glyphs. In most cases, this should be DWRITE_RENDERING_MODE_DEFAULT to automatically use an appropriate mode.</param>
- /// <param name="renderingParams">Holds the newly created rendering parameters object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateCustomRenderingParams)(
- FLOAT gamma,
- FLOAT enhancedContrast,
- FLOAT clearTypeLevel,
- DWRITE_PIXEL_GEOMETRY pixelGeometry,
- DWRITE_RENDERING_MODE renderingMode,
- __out IDWriteRenderingParams** renderingParams
- ) PURE;
-
- /// <summary>
- /// Registers a font file loader with DirectWrite.
- /// </summary>
- /// <param name="fontFileLoader">Pointer to the implementation of the IDWriteFontFileLoader for a particular file resource type.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- /// <remarks>
- /// This function registers a font file loader with DirectWrite.
- /// Font file loader interface handles loading font file resources of a particular type from a key.
- /// The font file loader interface is recommended to be implemented by a singleton object.
- /// A given instance can only be registered once.
- /// Succeeding attempts will return an error that it has already been registered.
- /// IMPORTANT: font file loader implementations must not register themselves with DirectWrite
- /// inside their constructors and must not unregister themselves in their destructors, because
- /// registration and unregistraton operations increment and decrement the object reference count respectively.
- /// Instead, registration and unregistration of font file loaders with DirectWrite should be performed
- /// outside of the font file loader implementation as a separate step.
- /// </remarks>
- STDMETHOD(RegisterFontFileLoader)(
- IDWriteFontFileLoader* fontFileLoader
- ) PURE;
-
- /// <summary>
- /// Unregisters a font file loader that was previously registered with the DirectWrite font system using RegisterFontFileLoader.
- /// </summary>
- /// <param name="fontFileLoader">Pointer to the file loader that was previously registered with the DirectWrite font system using RegisterFontFileLoader.</param>
- /// <returns>
- /// This function will succeed if the user loader is requested to be removed.
- /// It will fail if the pointer to the file loader identifies a standard DirectWrite loader,
- /// or a loader that is never registered or has already been unregistered.
- /// </returns>
- /// <remarks>
- /// This function unregisters font file loader callbacks with the DirectWrite font system.
- /// The font file loader interface is recommended to be implemented by a singleton object.
- /// IMPORTANT: font file loader implementations must not register themselves with DirectWrite
- /// inside their constructors and must not unregister themselves in their destructors, because
- /// registration and unregistraton operations increment and decrement the object reference count respectively.
- /// Instead, registration and unregistration of font file loaders with DirectWrite should be performed
- /// outside of the font file loader implementation as a separate step.
- /// </remarks>
- STDMETHOD(UnregisterFontFileLoader)(
- IDWriteFontFileLoader* fontFileLoader
- ) PURE;
-
- /// <summary>
- /// Create a text format object used for text layout.
- /// </summary>
- /// <param name="fontFamilyName">Name of the font family</param>
- /// <param name="fontCollection">Font collection. NULL indicates the system font collection.</param>
- /// <param name="fontWeight">Font weight</param>
- /// <param name="fontStyle">Font style</param>
- /// <param name="fontStretch">Font stretch</param>
- /// <param name="fontSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
- /// <param name="localeName">Locale name</param>
- /// <param name="textFormat">Contains newly created text format object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateTextFormat)(
- __in_z WCHAR const* fontFamilyName,
- __maybenull IDWriteFontCollection* fontCollection,
- DWRITE_FONT_WEIGHT fontWeight,
- DWRITE_FONT_STYLE fontStyle,
- DWRITE_FONT_STRETCH fontStretch,
- FLOAT fontSize,
- __in_z WCHAR const* localeName,
- __out IDWriteTextFormat** textFormat
- ) PURE;
-
- /// <summary>
- /// Create a typography object used in conjunction with text format for text layout.
- /// </summary>
- /// <param name="typography">Contains newly created typography object, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateTypography)(
- __out IDWriteTypography** typography
- ) PURE;
-
- /// <summary>
- /// Create an object used for interoperability with GDI.
- /// </summary>
- /// <param name="gdiInterop">Receives the GDI interop object if successful, or NULL in case of failure.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(GetGdiInterop)(
- __out IDWriteGdiInterop** gdiInterop
- ) PURE;
-
- /// <summary>
- /// CreateTextLayout takes a string, format, and associated constraints
- /// and produces and object representing the fully analyzed
- /// and formatted result.
- /// </summary>
- /// <param name="string">The string to layout.</param>
- /// <param name="stringLength">The length of the string.</param>
- /// <param name="textFormat">The format to apply to the string.</param>
- /// <param name="maxWidth">Width of the layout box.</param>
- /// <param name="maxHeight">Height of the layout box.</param>
- /// <param name="textLayout">The resultant object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateTextLayout)(
- __in_ecount(stringLength) WCHAR const* string,
- UINT32 stringLength,
- IDWriteTextFormat* textFormat,
- FLOAT maxWidth,
- FLOAT maxHeight,
- __out IDWriteTextLayout** textLayout
- ) PURE;
-
- /// <summary>
- /// CreateGdiCompatibleTextLayout takes a string, format, and associated constraints
- /// and produces and object representing the result formatted for a particular display resolution
- /// and measuring method. The resulting text layout should only be used for the intended resolution,
- /// and for cases where text scalability is desired, CreateTextLayout should be used instead.
- /// </summary>
- /// <param name="string">The string to layout.</param>
- /// <param name="stringLength">The length of the string.</param>
- /// <param name="textFormat">The format to apply to the string.</param>
- /// <param name="layoutWidth">Width of the layout box.</param>
- /// <param name="layoutHeight">Height of the layout box.</param>
- /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if rendering onto a 96 DPI device then pixelsPerDip
- /// is 1. If rendering onto a 120 DPI device then pixelsPerDip is 120/96.</param>
- /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
- /// scaling specified the font size and pixelsPerDip.</param>
- /// <param name="useGdiNatural">
- /// When set to FALSE, instructs the text layout to use the same metrics as GDI aliased text.
- /// When set to TRUE, instructs the text layout to use the same metrics as text measured by GDI using a font
- /// created with CLEARTYPE_NATURAL_QUALITY.
- /// </param>
- /// <param name="textLayout">The resultant object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateGdiCompatibleTextLayout)(
- __in_ecount(stringLength) WCHAR const* string,
- UINT32 stringLength,
- IDWriteTextFormat* textFormat,
- FLOAT layoutWidth,
- FLOAT layoutHeight,
- FLOAT pixelsPerDip,
- __in_opt DWRITE_MATRIX const* transform,
- BOOL useGdiNatural,
- __out IDWriteTextLayout** textLayout
- ) PURE;
-
- /// <summary>
- /// The application may call this function to create an inline object for trimming, using an ellipsis as the omission sign.
- /// The ellipsis will be created using the current settings of the format, including base font, style, and any effects.
- /// Alternate omission signs can be created by the application by implementing IDWriteInlineObject.
- /// </summary>
- /// <param name="textFormat">Text format used as a template for the omission sign.</param>
- /// <param name="trimmingSign">Created omission sign.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateEllipsisTrimmingSign)(
- IDWriteTextFormat* textFormat,
- __out IDWriteInlineObject** trimmingSign
- ) PURE;
-
- /// <summary>
- /// Return an interface to perform text analysis with.
- /// </summary>
- /// <param name="textAnalyzer">The resultant object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateTextAnalyzer)(
- __out IDWriteTextAnalyzer** textAnalyzer
- ) PURE;
-
- /// <summary>
- /// Creates a number substitution object using a locale name,
- /// substitution method, and whether to ignore user overrides (uses NLS
- /// defaults for the given culture instead).
- /// </summary>
- /// <param name="substitutionMethod">Method of number substitution to use.</param>
- /// <param name="localeName">Which locale to obtain the digits from.</param>
- /// <param name="ignoreUserOverride">Ignore the user's settings and use the locale defaults</param>
- /// <param name="numberSubstitution">Receives a pointer to the newly created object.</param>
- STDMETHOD(CreateNumberSubstitution)(
- __in DWRITE_NUMBER_SUBSTITUTION_METHOD substitutionMethod,
- __in_z WCHAR const* localeName,
- __in BOOL ignoreUserOverride,
- __out IDWriteNumberSubstitution** numberSubstitution
- ) PURE;
-
- /// <summary>
- /// Creates a glyph run analysis object, which encapsulates information
- /// used to render a glyph run.
- /// </summary>
- /// <param name="glyphRun">Structure specifying the properties of the glyph run.</param>
- /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if rendering onto a 96 DPI bitmap then pixelsPerDip
- /// is 1. If rendering onto a 120 DPI bitmap then pixelsPerDip is 120/96.</param>
- /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
- /// scaling specified the emSize and pixelsPerDip.</param>
- /// <param name="renderingMode">Specifies the rendering mode, which must be one of the raster rendering modes (i.e., not default
- /// and not outline).</param>
- /// <param name="measuringMode">Specifies the method to measure glyphs.</param>
- /// <param name="baselineOriginX">Horizontal position of the baseline origin, in DIPs.</param>
- /// <param name="baselineOriginY">Vertical position of the baseline origin, in DIPs.</param>
- /// <param name="glyphRunAnalysis">Receives a pointer to the newly created object.</param>
- /// <returns>
- /// Standard HRESULT error code.
- /// </returns>
- STDMETHOD(CreateGlyphRunAnalysis)(
- __in DWRITE_GLYPH_RUN const* glyphRun,
- FLOAT pixelsPerDip,
- __in_opt DWRITE_MATRIX const* transform,
- DWRITE_RENDERING_MODE renderingMode,
- DWRITE_MEASURING_MODE measuringMode,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- __out IDWriteGlyphRunAnalysis** glyphRunAnalysis
- ) PURE;
-
-}; // interface IDWriteFactory
-
-/// <summary>
-/// Creates a DirectWrite factory object that is used for subsequent creation of individual DirectWrite objects.
-/// </summary>
-/// <param name="factoryType">Identifies whether the factory object will be shared or isolated.</param>
-/// <param name="iid">Identifies the DirectWrite factory interface, such as __uuidof(IDWriteFactory).</param>
-/// <param name="factory">Receives the DirectWrite factory object.</param>
-/// <returns>
-/// Standard HRESULT error code.
-/// </returns>
-/// <remarks>
-/// Obtains DirectWrite factory object that is used for subsequent creation of individual DirectWrite classes.
-/// DirectWrite factory contains internal state such as font loader registration and cached font data.
-/// In most cases it is recommended to use the shared factory object, because it allows multiple components
-/// that use DirectWrite to share internal DirectWrite state and reduce memory usage.
-/// However, there are cases when it is desirable to reduce the impact of a component,
-/// such as a plug-in from an untrusted source, on the rest of the process by sandboxing and isolating it
-/// from the rest of the process components. In such cases, it is recommended to use an isolated factory for the sandboxed
-/// component.
-/// </remarks>
-EXTERN_C HRESULT DWRITE_EXPORT DWriteCreateFactory(
- __in DWRITE_FACTORY_TYPE factoryType,
- __in REFIID iid,
- __out IUnknown **factory
- );
-
-// Macros used to define DirectWrite error codes.
-#define FACILITY_DWRITE 0x898
-#define DWRITE_ERR_BASE 0x5000
-#define MAKE_DWRITE_HR(severity, code) MAKE_HRESULT(severity, FACILITY_DWRITE, (DWRITE_ERR_BASE + code))
-#define MAKE_DWRITE_HR_ERR(code) MAKE_DWRITE_HR(SEVERITY_ERROR, code)
-
-/// <summary>
-/// Indicates an error in an input file such as a font file.
-/// </summary>
-#define DWRITE_E_FILEFORMAT MAKE_DWRITE_HR_ERR(0x000)
-
-/// <summary>
-/// Indicates an error originating in DirectWrite code, which is not expected to occur but is safe to recover from.
-/// </summary>
-#define DWRITE_E_UNEXPECTED MAKE_DWRITE_HR_ERR(0x001)
-
-/// <summary>
-/// Indicates the specified font does not exist.
-/// </summary>
-#define DWRITE_E_NOFONT MAKE_DWRITE_HR_ERR(0x002)
-
-/// <summary>
-/// A font file could not be opened because the file, directory, network location, drive, or other storage
-/// location does not exist or is unavailable.
-/// </summary>
-#define DWRITE_E_FILENOTFOUND MAKE_DWRITE_HR_ERR(0x003)
-
-/// <summary>
-/// A font file exists but could not be opened due to access denied, sharing violation, or similar error.
-/// </summary>
-#define DWRITE_E_FILEACCESS MAKE_DWRITE_HR_ERR(0x004)
-
-/// <summary>
-/// A font collection is obsolete due to changes in the system.
-/// </summary>
-#define DWRITE_E_FONTCOLLECTIONOBSOLETE MAKE_DWRITE_HR_ERR(0x005)
-
-/// <summary>
-/// The given interface is already registered.
-/// </summary>
-#define DWRITE_E_ALREADYREGISTERED MAKE_DWRITE_HR_ERR(0x006)
-
-#endif /* DWRITE_H_INCLUDED */
+//+--------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Abstract:
+// DirectX Typography Services public API definitions.
+//
+//----------------------------------------------------------------------------
+
+#ifndef DWRITE_H_INCLUDED
+#define DWRITE_H_INCLUDED
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
+
+#ifndef DWRITE_NO_WINDOWS_H
+
+#include "specstrings.h"
+#include "unknwn.h"
+
+#endif // DWRITE_NO_WINDOWS_H
+
+#include "dcommon.h"
+
+#if _FX_COMPILER_ == _FX_VC6_
+typedef signed char INT8, *PINT8;
+typedef signed short INT16, *PINT16;
+typedef signed int INT32, *PINT32;
+typedef signed __int64 INT64, *PINT64;
+typedef unsigned char UINT8, *PUINT8;
+typedef unsigned short UINT16, *PUINT16;
+typedef unsigned int UINT32, *PUINT32;
+typedef unsigned __int64 UINT64, *PUINT64;
+#endif
+
+#ifndef DWRITE_DECLARE_INTERFACE
+#define DWRITE_DECLARE_INTERFACE(iid) DECLSPEC_UUID(iid) DECLSPEC_NOVTABLE
+#endif
+
+#ifndef DWRITE_EXPORT
+#define DWRITE_EXPORT __declspec(dllimport) WINAPI
+#endif
+
+/// <summary>
+/// The type of a font represented by a single font file.
+/// Font formats that consist of multiple files, e.g. Type 1 .PFM and .PFB, have
+/// separate enum values for each of the file type.
+/// </summary>
+enum DWRITE_FONT_FILE_TYPE
+{
+ /// <summary>
+ /// Font type is not recognized by the DirectWrite font system.
+ /// </summary>
+ DWRITE_FONT_FILE_TYPE_UNKNOWN,
+
+ /// <summary>
+ /// OpenType font with CFF outlines.
+ /// </summary>
+ DWRITE_FONT_FILE_TYPE_CFF,
+
+ /// <summary>
+ /// OpenType font with TrueType outlines.
+ /// </summary>
+ DWRITE_FONT_FILE_TYPE_TRUETYPE,
+
+ /// <summary>
+ /// OpenType font that contains a TrueType collection.
+ /// </summary>
+ DWRITE_FONT_FILE_TYPE_TRUETYPE_COLLECTION,
+
+ /// <summary>
+ /// Type 1 PFM font.
+ /// </summary>
+ DWRITE_FONT_FILE_TYPE_TYPE1_PFM,
+
+ /// <summary>
+ /// Type 1 PFB font.
+ /// </summary>
+ DWRITE_FONT_FILE_TYPE_TYPE1_PFB,
+
+ /// <summary>
+ /// Vector .FON font.
+ /// </summary>
+ DWRITE_FONT_FILE_TYPE_VECTOR,
+
+ /// <summary>
+ /// Bitmap .FON font.
+ /// </summary>
+ DWRITE_FONT_FILE_TYPE_BITMAP
+};
+
+/// <summary>
+/// The file format of a complete font face.
+/// Font formats that consist of multiple files, e.g. Type 1 .PFM and .PFB, have
+/// a single enum entry.
+/// </summary>
+enum DWRITE_FONT_FACE_TYPE
+{
+ /// <summary>
+ /// OpenType font face with CFF outlines.
+ /// </summary>
+ DWRITE_FONT_FACE_TYPE_CFF,
+
+ /// <summary>
+ /// OpenType font face with TrueType outlines.
+ /// </summary>
+ DWRITE_FONT_FACE_TYPE_TRUETYPE,
+
+ /// <summary>
+ /// OpenType font face that is a part of a TrueType collection.
+ /// </summary>
+ DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION,
+
+ /// <summary>
+ /// A Type 1 font face.
+ /// </summary>
+ DWRITE_FONT_FACE_TYPE_TYPE1,
+
+ /// <summary>
+ /// A vector .FON format font face.
+ /// </summary>
+ DWRITE_FONT_FACE_TYPE_VECTOR,
+
+ /// <summary>
+ /// A bitmap .FON format font face.
+ /// </summary>
+ DWRITE_FONT_FACE_TYPE_BITMAP,
+
+ /// <summary>
+ /// Font face type is not recognized by the DirectWrite font system.
+ /// </summary>
+ DWRITE_FONT_FACE_TYPE_UNKNOWN
+};
+
+/// <summary>
+/// Specifies algorithmic style simulations to be applied to the font face.
+/// Bold and oblique simulations can be combined via bitwise OR operation.
+/// </summary>
+enum DWRITE_FONT_SIMULATIONS
+{
+ /// <summary>
+ /// No simulations are performed.
+ /// </summary>
+ DWRITE_FONT_SIMULATIONS_NONE = 0x0000,
+
+ /// <summary>
+ /// Algorithmic emboldening is performed.
+ /// </summary>
+ DWRITE_FONT_SIMULATIONS_BOLD = 0x0001,
+
+ /// <summary>
+ /// Algorithmic italicization is performed.
+ /// </summary>
+ DWRITE_FONT_SIMULATIONS_OBLIQUE = 0x0002
+};
+
+#ifdef DEFINE_ENUM_FLAG_OPERATORS
+DEFINE_ENUM_FLAG_OPERATORS(DWRITE_FONT_SIMULATIONS);
+#endif
+
+/// <summary>
+/// The font weight enumeration describes common values for degree of blackness or thickness of strokes of characters in a font.
+/// Font weight values less than 1 or greater than 999 are considered to be invalid, and they are rejected by font API functions.
+/// </summary>
+enum DWRITE_FONT_WEIGHT
+{
+ /// <summary>
+ /// Predefined font weight : Thin (100).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_THIN = 100,
+
+ /// <summary>
+ /// Predefined font weight : Extra-light (200).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_EXTRA_LIGHT = 200,
+
+ /// <summary>
+ /// Predefined font weight : Ultra-light (200).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_ULTRA_LIGHT = 200,
+
+ /// <summary>
+ /// Predefined font weight : Light (300).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_LIGHT = 300,
+
+ /// <summary>
+ /// Predefined font weight : Normal (400).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_NORMAL = 400,
+
+ /// <summary>
+ /// Predefined font weight : Regular (400).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_REGULAR = 400,
+
+ /// <summary>
+ /// Predefined font weight : Medium (500).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_MEDIUM = 500,
+
+ /// <summary>
+ /// Predefined font weight : Demi-bold (600).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_DEMI_BOLD = 600,
+
+ /// <summary>
+ /// Predefined font weight : Semi-bold (600).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_SEMI_BOLD = 600,
+
+ /// <summary>
+ /// Predefined font weight : Bold (700).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_BOLD = 700,
+
+ /// <summary>
+ /// Predefined font weight : Extra-bold (800).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_EXTRA_BOLD = 800,
+
+ /// <summary>
+ /// Predefined font weight : Ultra-bold (800).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_ULTRA_BOLD = 800,
+
+ /// <summary>
+ /// Predefined font weight : Black (900).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_BLACK = 900,
+
+ /// <summary>
+ /// Predefined font weight : Heavy (900).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_HEAVY = 900,
+
+ /// <summary>
+ /// Predefined font weight : Extra-black (950).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_EXTRA_BLACK = 950,
+
+ /// <summary>
+ /// Predefined font weight : Ultra-black (950).
+ /// </summary>
+ DWRITE_FONT_WEIGHT_ULTRA_BLACK = 950
+};
+
+/// <summary>
+/// The font stretch enumeration describes relative change from the normal aspect ratio
+/// as specified by a font designer for the glyphs in a font.
+/// Values less than 1 or greater than 9 are considered to be invalid, and they are rejected by font API functions.
+/// </summary>
+enum DWRITE_FONT_STRETCH
+{
+ /// <summary>
+ /// Predefined font stretch : Not known (0).
+ /// </summary>
+ DWRITE_FONT_STRETCH_UNDEFINED = 0,
+
+ /// <summary>
+ /// Predefined font stretch : Ultra-condensed (1).
+ /// </summary>
+ DWRITE_FONT_STRETCH_ULTRA_CONDENSED = 1,
+
+ /// <summary>
+ /// Predefined font stretch : Extra-condensed (2).
+ /// </summary>
+ DWRITE_FONT_STRETCH_EXTRA_CONDENSED = 2,
+
+ /// <summary>
+ /// Predefined font stretch : Condensed (3).
+ /// </summary>
+ DWRITE_FONT_STRETCH_CONDENSED = 3,
+
+ /// <summary>
+ /// Predefined font stretch : Semi-condensed (4).
+ /// </summary>
+ DWRITE_FONT_STRETCH_SEMI_CONDENSED = 4,
+
+ /// <summary>
+ /// Predefined font stretch : Normal (5).
+ /// </summary>
+ DWRITE_FONT_STRETCH_NORMAL = 5,
+
+ /// <summary>
+ /// Predefined font stretch : Medium (5).
+ /// </summary>
+ DWRITE_FONT_STRETCH_MEDIUM = 5,
+
+ /// <summary>
+ /// Predefined font stretch : Semi-expanded (6).
+ /// </summary>
+ DWRITE_FONT_STRETCH_SEMI_EXPANDED = 6,
+
+ /// <summary>
+ /// Predefined font stretch : Expanded (7).
+ /// </summary>
+ DWRITE_FONT_STRETCH_EXPANDED = 7,
+
+ /// <summary>
+ /// Predefined font stretch : Extra-expanded (8).
+ /// </summary>
+ DWRITE_FONT_STRETCH_EXTRA_EXPANDED = 8,
+
+ /// <summary>
+ /// Predefined font stretch : Ultra-expanded (9).
+ /// </summary>
+ DWRITE_FONT_STRETCH_ULTRA_EXPANDED = 9
+};
+
+/// <summary>
+/// The font style enumeration describes the slope style of a font face, such as Normal, Italic or Oblique.
+/// Values other than the ones defined in the enumeration are considered to be invalid, and they are rejected by font API functions.
+/// </summary>
+enum DWRITE_FONT_STYLE
+{
+ /// <summary>
+ /// Font slope style : Normal.
+ /// </summary>
+ DWRITE_FONT_STYLE_NORMAL,
+
+ /// <summary>
+ /// Font slope style : Oblique.
+ /// </summary>
+ DWRITE_FONT_STYLE_OBLIQUE,
+
+ /// <summary>
+ /// Font slope style : Italic.
+ /// </summary>
+ DWRITE_FONT_STYLE_ITALIC
+
+};
+
+/// <summary>
+/// The informational string enumeration identifies a string in a font.
+/// </summary>
+enum DWRITE_INFORMATIONAL_STRING_ID
+{
+ /// <summary>
+ /// Unspecified name ID.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_NONE,
+
+ /// <summary>
+ /// Copyright notice provided by the font.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE,
+
+ /// <summary>
+ /// String containing a version number.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_VERSION_STRINGS,
+
+ /// <summary>
+ /// Trademark information provided by the font.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_TRADEMARK,
+
+ /// <summary>
+ /// Name of the font manufacturer.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
+
+ /// <summary>
+ /// Name of the font designer.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_DESIGNER,
+
+ /// <summary>
+ /// URL of font designer (with protocol, e.g., http://, ftp://).
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_DESIGNER_URL,
+
+ /// <summary>
+ /// Description of the font. Can contain revision information, usage recommendations, history, features, etc.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_DESCRIPTION,
+
+ /// <summary>
+ /// URL of font vendor (with protocol, e.g., http://, ftp://). If a unique serial number is embedded in the URL, it can be used to register the font.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_FONT_VENDOR_URL,
+
+ /// <summary>
+ /// Description of how the font may be legally used, or different example scenarios for licensed use. This field should be written in plain language, not legalese.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_LICENSE_DESCRIPTION,
+
+ /// <summary>
+ /// URL where additional licensing information can be found.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_LICENSE_INFO_URL,
+
+ /// <summary>
+ /// GDI-compatible family name. Because GDI allows a maximum of four fonts per family, fonts in the same family may have different GDI-compatible family names
+ /// (e.g., "Arial", "Arial Narrow", "Arial Black").
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES,
+
+ /// <summary>
+ /// GDI-compatible subfamily name.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES,
+
+ /// <summary>
+ /// Family name preferred by the designer. This enables font designers to group more than four fonts in a single family without losing compatibility with
+ /// GDI. This name is typically only present if it differs from the GDI-compatible family name.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_PREFERRED_FAMILY_NAMES,
+
+ /// <summary>
+ /// Subfamily name preferred by the designer. This name is typically only present if it differs from the GDI-compatible subfamily name.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_PREFERRED_SUBFAMILY_NAMES,
+
+ /// <summary>
+ /// Sample text. This can be the font name or any other text that the designer thinks is the best example to display the font in.
+ /// </summary>
+ DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT
+};
+
+
+/// <summary>
+/// The DWRITE_FONT_METRICS structure specifies the metrics of a font face that
+/// are applicable to all glyphs within the font face.
+/// </summary>
+struct DWRITE_FONT_METRICS
+{
+ /// <summary>
+ /// The number of font design units per em unit.
+ /// Font files use their own coordinate system of font design units.
+ /// A font design unit is the smallest measurable unit in the em square,
+ /// an imaginary square that is used to size and align glyphs.
+ /// The concept of em square is used as a reference scale factor when defining font size and device transformation semantics.
+ /// The size of one em square is also commonly used to compute the paragraph identation value.
+ /// </summary>
+ UINT16 designUnitsPerEm;
+
+ /// <summary>
+ /// Ascent value of the font face in font design units.
+ /// Ascent is the distance from the top of font character alignment box to English baseline.
+ /// </summary>
+ UINT16 ascent;
+
+ /// <summary>
+ /// Descent value of the font face in font design units.
+ /// Descent is the distance from the bottom of font character alignment box to English baseline.
+ /// </summary>
+ UINT16 descent;
+
+ /// <summary>
+ /// Line gap in font design units.
+ /// Recommended additional white space to add between lines to improve legibility. The recommended line spacing
+ /// (baseline-to-baseline distance) is thus the sum of ascent, descent, and lineGap. The line gap is usually
+ /// positive or zero but can be negative, in which case the recommended line spacing is less than the height
+ /// of the character alignment box.
+ /// </summary>
+ INT16 lineGap;
+
+ /// <summary>
+ /// Cap height value of the font face in font design units.
+ /// Cap height is the distance from English baseline to the top of a typical English capital.
+ /// Capital "H" is often used as a reference character for the purpose of calculating the cap height value.
+ /// </summary>
+ UINT16 capHeight;
+
+ /// <summary>
+ /// x-height value of the font face in font design units.
+ /// x-height is the distance from English baseline to the top of lowercase letter "x", or a similar lowercase character.
+ /// </summary>
+ UINT16 xHeight;
+
+ /// <summary>
+ /// The underline position value of the font face in font design units.
+ /// Underline position is the position of underline relative to the English baseline.
+ /// The value is usually made negative in order to place the underline below the baseline.
+ /// </summary>
+ INT16 underlinePosition;
+
+ /// <summary>
+ /// The suggested underline thickness value of the font face in font design units.
+ /// </summary>
+ UINT16 underlineThickness;
+
+ /// <summary>
+ /// The strikethrough position value of the font face in font design units.
+ /// Strikethrough position is the position of strikethrough relative to the English baseline.
+ /// The value is usually made positive in order to place the strikethrough above the baseline.
+ /// </summary>
+ INT16 strikethroughPosition;
+
+ /// <summary>
+ /// The suggested strikethrough thickness value of the font face in font design units.
+ /// </summary>
+ UINT16 strikethroughThickness;
+};
+
+/// <summary>
+/// The DWRITE_GLYPH_METRICS structure specifies the metrics of an individual glyph.
+/// The units depend on how the metrics are obtained.
+/// </summary>
+struct DWRITE_GLYPH_METRICS
+{
+ /// <summary>
+ /// Specifies the X offset from the glyph origin to the left edge of the black box.
+ /// The glyph origin is the current horizontal writing position.
+ /// A negative value means the black box extends to the left of the origin (often true for lowercase italic 'f').
+ /// </summary>
+ INT32 leftSideBearing;
+
+ /// <summary>
+ /// Specifies the X offset from the origin of the current glyph to the origin of the next glyph when writing horizontally.
+ /// </summary>
+ UINT32 advanceWidth;
+
+ /// <summary>
+ /// Specifies the X offset from the right edge of the black box to the origin of the next glyph when writing horizontally.
+ /// The value is negative when the right edge of the black box overhangs the layout box.
+ /// </summary>
+ INT32 rightSideBearing;
+
+ /// <summary>
+ /// Specifies the vertical offset from the vertical origin to the top of the black box.
+ /// Thus, a positive value adds whitespace whereas a negative value means the glyph overhangs the top of the layout box.
+ /// </summary>
+ INT32 topSideBearing;
+
+ /// <summary>
+ /// Specifies the Y offset from the vertical origin of the current glyph to the vertical origin of the next glyph when writing vertically.
+ /// (Note that the term "origin" by itself denotes the horizontal origin. The vertical origin is different.
+ /// Its Y coordinate is specified by verticalOriginY value,
+ /// and its X coordinate is half the advanceWidth to the right of the horizontal origin).
+ /// </summary>
+ UINT32 advanceHeight;
+
+ /// <summary>
+ /// Specifies the vertical distance from the black box's bottom edge to the advance height.
+ /// Positive when the bottom edge of the black box is within the layout box.
+ /// Negative when the bottom edge of black box overhangs the layout box.
+ /// </summary>
+ INT32 bottomSideBearing;
+
+ /// <summary>
+ /// Specifies the Y coordinate of a glyph's vertical origin, in the font's design coordinate system.
+ /// The y coordinate of a glyph's vertical origin is the sum of the glyph's top side bearing
+ /// and the top (i.e. yMax) of the glyph's bounding box.
+ /// </summary>
+ INT32 verticalOriginY;
+};
+
+/// <summary>
+/// Optional adjustment to a glyph's position. An glyph offset changes the position of a glyph without affecting
+/// the pen position. Offsets are in logical, pre-transform units.
+/// </summary>
+struct DWRITE_GLYPH_OFFSET
+{
+ /// <summary>
+ /// Offset in the advance direction of the run. A positive advance offset moves the glyph to the right
+ /// (in pre-transform coordinates) if the run is left-to-right or to the left if the run is right-to-left.
+ /// </summary>
+ FLOAT advanceOffset;
+
+ /// <summary>
+ /// Offset in the ascent direction, i.e., the direction ascenders point. A positive ascender offset moves
+ /// the glyph up (in pre-transform coordinates).
+ /// </summary>
+ FLOAT ascenderOffset;
+};
+
+/// <summary>
+/// Specifies the type of DirectWrite factory object.
+/// DirectWrite factory contains internal state such as font loader registration and cached font data.
+/// In most cases it is recommended to use the shared factory object, because it allows multiple components
+/// that use DirectWrite to share internal DirectWrite state and reduce memory usage.
+/// However, there are cases when it is desirable to reduce the impact of a component,
+/// such as a plug-in from an untrusted source, on the rest of the process by sandboxing and isolating it
+/// from the rest of the process components. In such cases, it is recommended to use an isolated factory for the sandboxed
+/// component.
+/// </summary>
+enum DWRITE_FACTORY_TYPE
+{
+ /// <summary>
+ /// Shared factory allow for re-use of cached font data across multiple in process components.
+ /// Such factories also take advantage of cross process font caching components for better performance.
+ /// </summary>
+ DWRITE_FACTORY_TYPE_SHARED,
+
+ /// <summary>
+ /// Objects created from the isolated factory do not interact with internal DirectWrite state from other components.
+ /// </summary>
+ DWRITE_FACTORY_TYPE_ISOLATED
+};
+
+// Creates an OpenType tag as a 32bit integer such that
+// the first character in the tag is the lowest byte,
+// (least significant on little endian architectures)
+// which can be used to compare with tags in the font file.
+// This macro is compatible with DWRITE_FONT_FEATURE_TAG.
+//
+// Example: DWRITE_MAKE_OPENTYPE_TAG('c','c','m','p')
+// Dword: 0x706D6363
+//
+#define DWRITE_MAKE_OPENTYPE_TAG(a,b,c,d) ( \
+ (static_cast<UINT32>(static_cast<UINT8>(d)) << 24) | \
+ (static_cast<UINT32>(static_cast<UINT8>(c)) << 16) | \
+ (static_cast<UINT32>(static_cast<UINT8>(b)) << 8) | \
+ static_cast<UINT32>(static_cast<UINT8>(a)))
+
+interface IDWriteFontFileStream;
+
+/// <summary>
+/// Font file loader interface handles loading font file resources of a particular type from a key.
+/// The font file loader interface is recommended to be implemented by a singleton object.
+/// IMPORTANT: font file loader implementations must not register themselves with DirectWrite factory
+/// inside their constructors and must not unregister themselves in their destructors, because
+/// registration and unregistraton operations increment and decrement the object reference count respectively.
+/// Instead, registration and unregistration of font file loaders with DirectWrite factory should be performed
+/// outside of the font file loader implementation as a separate step.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("727cad4e-d6af-4c9e-8a08-d695b11caa49") IDWriteFontFileLoader : public IUnknown
+{
+ /// <summary>
+ /// Creates a font file stream object that encapsulates an open file resource.
+ /// The resource is closed when the last reference to fontFileStream is released.
+ /// </summary>
+ /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the font file resource
+ /// within the scope of the font loader being used.</param>
+ /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
+ /// <param name="fontFileStream">Pointer to the newly created font file stream.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateStreamFromKey)(
+ __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ __out IDWriteFontFileStream** fontFileStream
+ ) PURE;
+};
+
+/// <summary>
+/// A built-in implementation of IDWriteFontFileLoader interface that operates on local font files
+/// and exposes local font file information from the font file reference key.
+/// Font file references created using CreateFontFileReference use this font file loader.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("b2d9f3ec-c9fe-4a11-a2ec-d86208f7c0a2") IDWriteLocalFontFileLoader : public IDWriteFontFileLoader
+{
+ /// <summary>
+ /// Obtains the length of the absolute file path from the font file reference key.
+ /// </summary>
+ /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the local font file
+ /// within the scope of the font loader being used.</param>
+ /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
+ /// <param name="filePathLength">Length of the file path string not including the terminated NULL character.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFilePathLengthFromKey)(
+ __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ __out UINT32* filePathLength
+ ) PURE;
+
+ /// <summary>
+ /// Obtains the absolute font file path from the font file reference key.
+ /// </summary>
+ /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the local font file
+ /// within the scope of the font loader being used.</param>
+ /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
+ /// <param name="filePath">Character array that receives the local file path.</param>
+ /// <param name="filePathSize">Size of the filePath array in character count including the terminated NULL character.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFilePathFromKey)(
+ __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ __out_ecount_z(filePathSize) WCHAR* filePath,
+ UINT32 filePathSize
+ ) PURE;
+
+ /// <summary>
+ /// Obtains the last write time of the file from the font file reference key.
+ /// </summary>
+ /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the local font file
+ /// within the scope of the font loader being used.</param>
+ /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
+ /// <param name="lastWriteTime">Last modified time of the font file.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetLastWriteTimeFromKey)(
+ __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ __out FILETIME* lastWriteTime
+ ) PURE;
+};
+
+/// <summary>
+/// The interface for loading font file data.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("6d4865fe-0ab8-4d91-8f62-5dd6be34a3e0") IDWriteFontFileStream : public IUnknown
+{
+ /// <summary>
+ /// Reads a fragment from a file.
+ /// </summary>
+ /// <param name="fragmentStart">Receives the pointer to the start of the font file fragment.</param>
+ /// <param name="fileOffset">Offset of the fragment from the beginning of the font file.</param>
+ /// <param name="fragmentSize">Size of the fragment in bytes.</param>
+ /// <param name="fragmentContext">The client defined context to be passed to the ReleaseFileFragment.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// IMPORTANT: ReadFileFragment() implementations must check whether the requested file fragment
+ /// is within the file bounds. Otherwise, an error should be returned from ReadFileFragment.
+ /// </remarks>
+ STDMETHOD(ReadFileFragment)(
+ __deref_out_bcount(fragmentSize) void const** fragmentStart,
+ UINT64 fileOffset,
+ UINT64 fragmentSize,
+ __out void** fragmentContext
+ ) PURE;
+
+ /// <summary>
+ /// Releases a fragment from a file.
+ /// </summary>
+ /// <param name="fragmentContext">The client defined context of a font fragment returned from ReadFileFragment.</param>
+ STDMETHOD_(void, ReleaseFileFragment)(
+ void* fragmentContext
+ ) PURE;
+
+ /// <summary>
+ /// Obtains the total size of a file.
+ /// </summary>
+ /// <param name="fileSize">Receives the total size of the file.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// Implementing GetFileSize() for asynchronously loaded font files may require
+ /// downloading the complete file contents, therefore this method should only be used for operations that
+ /// either require complete font file to be loaded (e.g., copying a font file) or need to make
+ /// decisions based on the value of the file size (e.g., validation against a persisted file size).
+ /// </remarks>
+ STDMETHOD(GetFileSize)(
+ __out UINT64* fileSize
+ ) PURE;
+
+ /// <summary>
+ /// Obtains the last modified time of the file. The last modified time is used by DirectWrite font selection algorithms
+ /// to determine whether one font resource is more up to date than another one.
+ /// </summary>
+ /// <param name="lastWriteTime">Receives the last modifed time of the file in the format that represents
+ /// the number of 100-nanosecond intervals since January 1, 1601 (UTC).</param>
+ /// <returns>
+ /// Standard HRESULT error code. For resources that don't have a concept of the last modified time, the implementation of
+ /// GetLastWriteTime should return E_NOTIMPL.
+ /// </returns>
+ STDMETHOD(GetLastWriteTime)(
+ __out UINT64* lastWriteTime
+ ) PURE;
+};
+
+/// <summary>
+/// The interface that represents a reference to a font file.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("739d886a-cef5-47dc-8769-1a8b41bebbb0") IDWriteFontFile : public IUnknown
+{
+ /// <summary>
+ /// This method obtains the pointer to the reference key of a font file. The pointer is only valid until the object that refers to it is released.
+ /// </summary>
+ /// <param name="fontFileReferenceKey">Pointer to the font file reference key.
+ /// IMPORTANT: The pointer value is valid until the font file reference object it is obtained from is released.</param>
+ /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetReferenceKey)(
+ __deref_out_bcount(*fontFileReferenceKeySize) void const** fontFileReferenceKey,
+ __out UINT32* fontFileReferenceKeySize
+ ) PURE;
+
+ /// <summary>
+ /// Obtains the file loader associated with a font file object.
+ /// </summary>
+ /// <param name="fontFileLoader">The font file loader associated with the font file object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetLoader)(
+ __out IDWriteFontFileLoader** fontFileLoader
+ ) PURE;
+
+ /// <summary>
+ /// Analyzes a file and returns whether it represents a font, and whether the font type is supported by the font system.
+ /// </summary>
+ /// <param name="isSupportedFontType">TRUE if the font type is supported by the font system, FALSE otherwise.</param>
+ /// <param name="fontFileType">The type of the font file. Note that even if isSupportedFontType is FALSE,
+ /// the fontFileType value may be different from DWRITE_FONT_FILE_TYPE_UNKNOWN.</param>
+ /// <param name="fontFaceType">The type of the font face that can be constructed from the font file.
+ /// Note that even if isSupportedFontType is FALSE, the fontFaceType value may be different from
+ /// DWRITE_FONT_FACE_TYPE_UNKNOWN.</param>
+ /// <param name="numberOfFaces">Number of font faces contained in the font file.</param>
+ /// <returns>
+ /// Standard HRESULT error code if there was a processing error during analysis.
+ /// </returns>
+ /// <remarks>
+ /// IMPORTANT: certain font file types are recognized, but not supported by the font system.
+ /// For example, the font system will recognize a file as a Type 1 font file,
+ /// but will not be able to construct a font face object from it. In such situations, Analyze will set
+ /// isSupportedFontType output parameter to FALSE.
+ /// </remarks>
+ STDMETHOD(Analyze)(
+ __out BOOL* isSupportedFontType,
+ __out DWRITE_FONT_FILE_TYPE* fontFileType,
+ __out_opt DWRITE_FONT_FACE_TYPE* fontFaceType,
+ __out UINT32* numberOfFaces
+ ) PURE;
+};
+
+/// <summary>
+/// Represents the internal structure of a device pixel (i.e., the physical arrangement of red,
+/// green, and blue color components) that is assumed for purposes of rendering text.
+/// </summary>
+#ifndef DWRITE_PIXEL_GEOMETRY_DEFINED
+enum DWRITE_PIXEL_GEOMETRY
+{
+ /// <summary>
+ /// The red, green, and blue color components of each pixel are assumed to occupy the same point.
+ /// </summary>
+ DWRITE_PIXEL_GEOMETRY_FLAT,
+
+ /// <summary>
+ /// Each pixel comprises three vertical stripes, with red on the left, green in the center, and
+ /// blue on the right. This is the most common pixel geometry for LCD monitors.
+ /// </summary>
+ DWRITE_PIXEL_GEOMETRY_RGB,
+
+ /// <summary>
+ /// Each pixel comprises three vertical stripes, with blue on the left, green in the center, and
+ /// red on the right.
+ /// </summary>
+ DWRITE_PIXEL_GEOMETRY_BGR
+};
+#define DWRITE_PIXEL_GEOMETRY_DEFINED
+#endif
+
+/// <summary>
+/// Represents a method of rendering glyphs.
+/// </summary>
+enum DWRITE_RENDERING_MODE
+{
+ /// <summary>
+ /// Specifies that the rendering mode is determined automatically based on the font and size.
+ /// </summary>
+ DWRITE_RENDERING_MODE_DEFAULT,
+
+ /// <summary>
+ /// Specifies that no anti-aliasing is performed. Each pixel is either set to the foreground
+ /// color of the text or retains the color of the background.
+ /// </summary>
+ DWRITE_RENDERING_MODE_ALIASED,
+
+ /// <summary>
+ /// Specifies ClearType rendering with the same metrics as aliased text. Glyphs can only
+ /// be positioned on whole-pixel boundaries.
+ /// </summary>
+ DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC,
+
+ /// <summary>
+ /// Specifies ClearType rendering with the same metrics as text rendering using GDI using a font
+ /// created with CLEARTYPE_NATURAL_QUALITY. Glyph metrics are closer to their ideal values than
+ /// with aliased text, but glyphs are still positioned on whole-pixel boundaries.
+ /// </summary>
+ DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL,
+
+ /// <summary>
+ /// Specifies ClearType rendering with anti-aliasing in the horizontal dimension only. This is
+ /// typically used with small to medium font sizes (up to 16 ppem).
+ /// </summary>
+ DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL,
+
+ /// <summary>
+ /// Specifies ClearType rendering with anti-aliasing in both horizontal and vertical dimensions.
+ /// This is typically used at larger sizes to makes curves and diagonal lines look smoother, at
+ /// the expense of some softness.
+ /// </summary>
+ DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
+
+ /// <summary>
+ /// Specifies that rendering should bypass the rasterizer and use the outlines directly. This is
+ /// typically used at very large sizes.
+ /// </summary>
+ DWRITE_RENDERING_MODE_OUTLINE
+};
+
+/// <summary>
+/// The DWRITE_MATRIX structure specifies the graphics transform to be applied
+/// to rendered glyphs.
+/// </summary>
+struct DWRITE_MATRIX
+{
+ /// <summary>
+ /// Horizontal scaling / cosine of rotation
+ /// </summary>
+ FLOAT m11;
+
+ /// <summary>
+ /// Vertical shear / sine of rotation
+ /// </summary>
+ FLOAT m12;
+
+ /// <summary>
+ /// Horizontal shear / negative sine of rotation
+ /// </summary>
+ FLOAT m21;
+
+ /// <summary>
+ /// Vertical scaling / cosine of rotation
+ /// </summary>
+ FLOAT m22;
+
+ /// <summary>
+ /// Horizontal shift (always orthogonal regardless of rotation)
+ /// </summary>
+ FLOAT dx;
+
+ /// <summary>
+ /// Vertical shift (always orthogonal regardless of rotation)
+ /// </summary>
+ FLOAT dy;
+};
+
+/// <summary>
+/// The interface that represents text rendering settings for glyph rasterization and filtering.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("2f0da53a-2add-47cd-82ee-d9ec34688e75") IDWriteRenderingParams : public IUnknown
+{
+ /// <summary>
+ /// Gets the gamma value used for gamma correction. Valid values must be
+ /// greater than zero and cannot exceed 256.
+ /// </summary>
+ STDMETHOD_(FLOAT, GetGamma)() PURE;
+
+ /// <summary>
+ /// Gets the amount of contrast enhancement. Valid values are greater than
+ /// or equal to zero.
+ /// </summary>
+ STDMETHOD_(FLOAT, GetEnhancedContrast)() PURE;
+
+ /// <summary>
+ /// Gets the ClearType level. Valid values range from 0.0f (no ClearType)
+ /// to 1.0f (full ClearType).
+ /// </summary>
+ STDMETHOD_(FLOAT, GetClearTypeLevel)() PURE;
+
+ /// <summary>
+ /// Gets the pixel geometry.
+ /// </summary>
+ STDMETHOD_(DWRITE_PIXEL_GEOMETRY, GetPixelGeometry)() PURE;
+
+ /// <summary>
+ /// Gets the rendering mode.
+ /// </summary>
+ STDMETHOD_(DWRITE_RENDERING_MODE, GetRenderingMode)() PURE;
+};
+
+// Forward declarations of D2D types
+interface ID2D1SimplifiedGeometrySink;
+
+typedef ID2D1SimplifiedGeometrySink IDWriteGeometrySink;
+
+/// <summary>
+/// The interface that represents an absolute reference to a font face.
+/// It contains font face type, appropriate file references and face identification data.
+/// Various font data such as metrics, names and glyph outlines is obtained from IDWriteFontFace.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("5f49804d-7024-4d43-bfa9-d25984f53849") IDWriteFontFace : public IUnknown
+{
+ /// <summary>
+ /// Obtains the file format type of a font face.
+ /// </summary>
+ STDMETHOD_(DWRITE_FONT_FACE_TYPE, GetType)() PURE;
+
+ /// <summary>
+ /// Obtains the font files representing a font face.
+ /// </summary>
+ /// <param name="numberOfFiles">The number of files representing the font face.</param>
+ /// <param name="fontFiles">User provided array that stores pointers to font files representing the font face.
+ /// This parameter can be NULL if the user is only interested in the number of files representing the font face.
+ /// This API increments reference count of the font file pointers returned according to COM conventions, and the client
+ /// should release them when finished.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFiles)(
+ __inout UINT32* numberOfFiles,
+ __out_ecount_opt(*numberOfFiles) IDWriteFontFile** fontFiles
+ ) PURE;
+
+ /// <summary>
+ /// Obtains the zero-based index of the font face in its font file or files. If the font files contain a single face,
+ /// the return value is zero.
+ /// </summary>
+ STDMETHOD_(UINT32, GetIndex)() PURE;
+
+ /// <summary>
+ /// Obtains the algorithmic style simulation flags of a font face.
+ /// </summary>
+ STDMETHOD_(DWRITE_FONT_SIMULATIONS, GetSimulations)() PURE;
+
+ /// <summary>
+ /// Determines whether the font is a symbol font.
+ /// </summary>
+ STDMETHOD_(BOOL, IsSymbolFont)() PURE;
+
+ /// <summary>
+ /// Obtains design units and common metrics for the font face.
+ /// These metrics are applicable to all the glyphs within a fontface and are used by applications for layout calculations.
+ /// </summary>
+ /// <param name="fontFaceMetrics">Points to a DWRITE_FONT_METRICS structure to fill in.
+ /// The metrics returned by this function are in font design units.</param>
+ STDMETHOD_(void, GetMetrics)(
+ __out DWRITE_FONT_METRICS* fontFaceMetrics
+ ) PURE;
+
+ /// <summary>
+ /// Obtains the number of glyphs in the font face.
+ /// </summary>
+ STDMETHOD_(UINT16, GetGlyphCount)() PURE;
+
+ /// <summary>
+ /// Obtains ideal glyph metrics in font design units. Design glyphs metrics are used for glyph positioning.
+ /// </summary>
+ /// <param name="glyphIndices">An array of glyph indices to compute the metrics for.</param>
+ /// <param name="glyphCount">The number of elements in the glyphIndices array.</param>
+ /// <param name="glyphMetrics">Array of DWRITE_GLYPH_METRICS structures filled by this function.
+ /// The metrics returned by this function are in font design units.</param>
+ /// <param name="isSideways">Indicates whether the font is being used in a sideways run.
+ /// This can affect the glyph metrics if the font has oblique simulation
+ /// because sideways oblique simulation differs from non-sideways oblique simulation.</param>
+ /// <returns>
+ /// Standard HRESULT error code. If any of the input glyph indices are outside of the valid glyph index range
+ /// for the current font face, E_INVALIDARG will be returned.
+ /// </returns>
+ STDMETHOD(GetDesignGlyphMetrics)(
+ __in_ecount(glyphCount) UINT16 const* glyphIndices,
+ UINT32 glyphCount,
+ __out_ecount(glyphCount) DWRITE_GLYPH_METRICS* glyphMetrics,
+ BOOL isSideways = FALSE
+ ) PURE;
+
+ /// <summary>
+ /// Returns the nominal mapping of UCS4 Unicode code points to glyph indices as defined by the font 'CMAP' table.
+ /// Note that this mapping is primarily provided for line layout engines built on top of the physical font API.
+ /// Because of OpenType glyph substitution and line layout character substitution, the nominal conversion does not always correspond
+ /// to how a Unicode string will map to glyph indices when rendering using a particular font face.
+ /// Also, note that Unicode Variant Selectors provide for alternate mappings for character to glyph.
+ /// This call will always return the default variant.
+ /// </summary>
+ /// <param name="codePoints">An array of USC4 code points to obtain nominal glyph indices from.</param>
+ /// <param name="codePointCount">The number of elements in the codePoints array.</param>
+ /// <param name="glyphIndices">Array of nominal glyph indices filled by this function.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetGlyphIndices)(
+ __in_ecount(codePointCount) UINT32 const* codePoints,
+ UINT32 codePointCount,
+ __out_ecount(codePointCount) UINT16* glyphIndices
+ ) PURE;
+
+ /// <summary>
+ /// Finds the specified OpenType font table if it exists and returns a pointer to it.
+ /// The function accesses the underling font data via the IDWriteFontStream interface
+ /// implemented by the font file loader.
+ /// </summary>
+ /// <param name="openTypeTableTag">Four character tag of table to find.
+ /// Use the DWRITE_MAKE_OPENTYPE_TAG() macro to create it.
+ /// Unlike GDI, it does not support the special TTCF and null tags to access the whole font.</param>
+ /// <param name="tableData">
+ /// Pointer to base of table in memory.
+ /// The pointer is only valid so long as the FontFace used to get the font table still exists
+ /// (not any other FontFace, even if it actually refers to the same physical font).
+ /// </param>
+ /// <param name="tableSize">Byte size of table.</param>
+ /// <param name="tableContext">
+ /// Opaque context which must be freed by calling ReleaseFontTable.
+ /// The context actually comes from the lower level IDWriteFontFileStream,
+ /// which may be implemented by the application or DWrite itself.
+ /// It is possible for a NULL tableContext to be returned, especially if
+ /// the implementation directly memory maps the whole file.
+ /// Nevertheless, always release it later, and do not use it as a test for function success.
+ /// The same table can be queried multiple times,
+ /// but each returned context can be different, so release each separately.
+ /// </param>
+ /// <param name="exists">True if table exists.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// If a table can not be found, the function will not return an error, but the size will be 0, table NULL, and exists = FALSE.
+ /// The context does not need to be freed if the table was not found.
+ /// </returns>
+ /// <remarks>
+ /// The context for the same tag may be different for each call,
+ /// so each one must be held and released separately.
+ /// </remarks>
+ STDMETHOD(TryGetFontTable)(
+ __in UINT32 openTypeTableTag,
+ __deref_out_bcount(*tableSize) const void** tableData,
+ __out UINT32* tableSize,
+ __out void** tableContext,
+ __out BOOL* exists
+ ) PURE;
+
+ /// <summary>
+ /// Releases the table obtained earlier from TryGetFontTable.
+ /// </summary>
+ /// <param name="tableContext">Opaque context from TryGetFontTable.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD_(void, ReleaseFontTable)(
+ __in void* tableContext
+ ) PURE;
+
+ /// <summary>
+ /// Computes the outline of a run of glyphs by calling back to the outline sink interface.
+ /// </summary>
+ /// <param name="emSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
+ /// <param name="glyphIndices">Array of glyph indices.</param>
+ /// <param name="glyphAdvances">Optional array of glyph advances in DIPs.</param>
+ /// <param name="glyphOffsets">Optional array of glyph offsets.</param>
+ /// <param name="glyphCount">Number of glyphs.</param>
+ /// <param name="isSideways">If true, specifies that glyphs are rotated 90 degrees to the left and vertical metrics are used.
+ /// A client can render a vertical run by specifying isSideways = true and rotating the resulting geometry 90 degrees to the
+ /// right using a transform. The isSideways and isRightToLeft parameters cannot both be true.</param>
+ /// <param name="isRightToLeft">If true, specifies that the advance direction is right to left. By default, the advance direction
+ /// is left to right.</param>
+ /// <param name="geometrySink">Interface the function calls back to draw each element of the geometry.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetGlyphRunOutline)(
+ FLOAT emSize,
+ __in_ecount(glyphCount) UINT16 const* glyphIndices,
+ __in_ecount_opt(glyphCount) FLOAT const* glyphAdvances,
+ __in_ecount_opt(glyphCount) DWRITE_GLYPH_OFFSET const* glyphOffsets,
+ UINT32 glyphCount,
+ BOOL isSideways,
+ BOOL isRightToLeft,
+ IDWriteGeometrySink* geometrySink
+ ) PURE;
+
+ /// <summary>
+ /// Determines the recommended rendering mode for the font given the specified size and rendering parameters.
+ /// </summary>
+ /// <param name="emSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
+ /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this
+ /// value is 1.0f. If the DPI is 120, this value is 120.0f/96.</param>
+ /// <param name="measuringMode">Specifies measuring method that will be used for glyphs in the font.
+ /// Renderer implementations may choose different rendering modes for given measuring methods, but
+ /// best results are seen when the corresponding modes match:
+ /// DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL for DWRITE_MEASURING_MODE_NATURAL
+ /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC for DWRITE_MEASURING_MODE_GDI_CLASSIC
+ /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL for DWRITE_MEASURING_MODE_GDI_NATURAL
+ /// </param>
+ /// <param name="renderingParams">Rendering parameters object. This parameter is necessary in case the rendering parameters
+ /// object overrides the rendering mode.</param>
+ /// <param name="renderingMode">Receives the recommended rendering mode to use.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetRecommendedRenderingMode)(
+ FLOAT emSize,
+ FLOAT pixelsPerDip,
+ DWRITE_MEASURING_MODE measuringMode,
+ IDWriteRenderingParams* renderingParams,
+ __out DWRITE_RENDERING_MODE* renderingMode
+ ) PURE;
+
+ /// <summary>
+ /// Obtains design units and common metrics for the font face.
+ /// These metrics are applicable to all the glyphs within a fontface and are used by applications for layout calculations.
+ /// </summary>
+ /// <param name="emSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
+ /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this
+ /// value is 1.0f. If the DPI is 120, this value is 120.0f/96.</param>
+ /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
+ /// scaling specified by the font size and pixelsPerDip.</param>
+ /// <param name="fontFaceMetrics">Points to a DWRITE_FONT_METRICS structure to fill in.
+ /// The metrics returned by this function are in font design units.</param>
+ STDMETHOD(GetGdiCompatibleMetrics)(
+ FLOAT emSize,
+ FLOAT pixelsPerDip,
+ __in_opt DWRITE_MATRIX const* transform,
+ __out DWRITE_FONT_METRICS* fontFaceMetrics
+ ) PURE;
+
+
+ /// <summary>
+ /// Obtains glyph metrics in font design units with the return values compatible with what GDI would produce.
+ /// Glyphs metrics are used for positioning of individual glyphs.
+ /// </summary>
+ /// <param name="emSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
+ /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this
+ /// value is 1.0f. If the DPI is 120, this value is 120.0f/96.</param>
+ /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
+ /// scaling specified by the font size and pixelsPerDip.</param>
+ /// <param name="useGdiNatural">
+ /// When set to FALSE, the metrics are the same as the metrics of GDI aliased text.
+ /// When set to TRUE, the metrics are the same as the metrics of text measured by GDI using a font
+ /// created with CLEARTYPE_NATURAL_QUALITY.
+ /// </param>
+ /// <param name="glyphIndices">An array of glyph indices to compute the metrics for.</param>
+ /// <param name="glyphCount">The number of elements in the glyphIndices array.</param>
+ /// <param name="glyphMetrics">Array of DWRITE_GLYPH_METRICS structures filled by this function.
+ /// The metrics returned by this function are in font design units.</param>
+ /// <param name="isSideways">Indicates whether the font is being used in a sideways run.
+ /// This can affect the glyph metrics if the font has oblique simulation
+ /// because sideways oblique simulation differs from non-sideways oblique simulation.</param>
+ /// <returns>
+ /// Standard HRESULT error code. If any of the input glyph indices are outside of the valid glyph index range
+ /// for the current font face, E_INVALIDARG will be returned.
+ /// </returns>
+ STDMETHOD(GetGdiCompatibleGlyphMetrics)(
+ FLOAT emSize,
+ FLOAT pixelsPerDip,
+ __in_opt DWRITE_MATRIX const* transform,
+ BOOL useGdiNatural,
+ __in_ecount(glyphCount) UINT16 const* glyphIndices,
+ UINT32 glyphCount,
+ __out_ecount(glyphCount) DWRITE_GLYPH_METRICS* glyphMetrics,
+ BOOL isSideways = FALSE
+ ) PURE;
+};
+
+interface IDWriteFactory;
+interface IDWriteFontFileEnumerator;
+
+/// <summary>
+/// The font collection loader interface is used to construct a collection of fonts given a particular type of key.
+/// The font collection loader interface is recommended to be implemented by a singleton object.
+/// IMPORTANT: font collection loader implementations must not register themselves with a DirectWrite factory
+/// inside their constructors and must not unregister themselves in their destructors, because
+/// registration and unregistraton operations increment and decrement the object reference count respectively.
+/// Instead, registration and unregistration of font file loaders with DirectWrite factory should be performed
+/// outside of the font file loader implementation as a separate step.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("cca920e4-52f0-492b-bfa8-29c72ee0a468") IDWriteFontCollectionLoader : public IUnknown
+{
+ /// <summary>
+ /// Creates a font file enumerator object that encapsulates a collection of font files.
+ /// The font system calls back to this interface to create a font collection.
+ /// </summary>
+ /// <param name="factory">Factory associated with the loader.</param>
+ /// <param name="collectionKey">Font collection key that uniquely identifies the collection of font files within
+ /// the scope of the font collection loader being used.</param>
+ /// <param name="collectionKeySize">Size of the font collection key in bytes.</param>
+ /// <param name="fontFileEnumerator">Pointer to the newly created font file enumerator.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateEnumeratorFromKey)(
+ IDWriteFactory* factory,
+ __in_bcount(collectionKeySize) void const* collectionKey,
+ UINT32 collectionKeySize,
+ __out IDWriteFontFileEnumerator** fontFileEnumerator
+ ) PURE;
+};
+
+/// <summary>
+/// The font file enumerator interface encapsulates a collection of font files. The font system uses this interface
+/// to enumerate font files when building a font collection.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("72755049-5ff7-435d-8348-4be97cfa6c7c") IDWriteFontFileEnumerator : public IUnknown
+{
+ /// <summary>
+ /// Advances to the next font file in the collection. When it is first created, the enumerator is positioned
+ /// before the first element of the collection and the first call to MoveNext advances to the first file.
+ /// </summary>
+ /// <param name="hasCurrentFile">Receives the value TRUE if the enumerator advances to a file, or FALSE if
+ /// the enumerator advanced past the last file in the collection.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(MoveNext)(
+ __out BOOL* hasCurrentFile
+ ) PURE;
+
+ /// <summary>
+ /// Gets a reference to the current font file.
+ /// </summary>
+ /// <param name="fontFile">Pointer to the newly created font file object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetCurrentFontFile)(
+ __out IDWriteFontFile** fontFile
+ ) PURE;
+};
+
+/// <summary>
+/// Represents a collection of strings indexed by locale name.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("08256209-099a-4b34-b86d-c22b110e7771") IDWriteLocalizedStrings : public IUnknown
+{
+ /// <summary>
+ /// Gets the number of language/string pairs.
+ /// </summary>
+ STDMETHOD_(UINT32, GetCount)() PURE;
+
+ /// <summary>
+ /// Gets the index of the item with the specified locale name.
+ /// </summary>
+ /// <param name="localeName">Locale name to look for.</param>
+ /// <param name="index">Receives the zero-based index of the locale name/string pair.</param>
+ /// <param name="exists">Receives TRUE if the locale name exists or FALSE if not.</param>
+ /// <returns>
+ /// Standard HRESULT error code. If the specified locale name does not exist, the return value is S_OK,
+ /// but *index is UINT_MAX and *exists is FALSE.
+ /// </returns>
+ STDMETHOD(FindLocaleName)(
+ __in_z WCHAR const* localeName,
+ __out UINT32* index,
+ __out BOOL* exists
+ ) PURE;
+
+ /// <summary>
+ /// Gets the length in characters (not including the null terminator) of the locale name with the specified index.
+ /// </summary>
+ /// <param name="index">Zero-based index of the locale name.</param>
+ /// <param name="length">Receives the length in characters, not including the null terminator.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetLocaleNameLength)(
+ UINT32 index,
+ __out UINT32* length
+ ) PURE;
+
+ /// <summary>
+ /// Copies the locale name with the specified index to the specified array.
+ /// </summary>
+ /// <param name="index">Zero-based index of the locale name.</param>
+ /// <param name="localeName">Character array that receives the locale name.</param>
+ /// <param name="size">Size of the array in characters. The size must include space for the terminating
+ /// null character.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetLocaleName)(
+ UINT32 index,
+ __out_ecount_z(size) WCHAR* localeName,
+ UINT32 size
+ ) PURE;
+
+ /// <summary>
+ /// Gets the length in characters (not including the null terminator) of the string with the specified index.
+ /// </summary>
+ /// <param name="index">Zero-based index of the string.</param>
+ /// <param name="length">Receives the length in characters, not including the null terminator.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetStringLength)(
+ UINT32 index,
+ __out UINT32* length
+ ) PURE;
+
+ /// <summary>
+ /// Copies the string with the specified index to the specified array.
+ /// </summary>
+ /// <param name="index">Zero-based index of the string.</param>
+ /// <param name="stringBuffer">Character array that receives the string.</param>
+ /// <param name="size">Size of the array in characters. The size must include space for the terminating
+ /// null character.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetString)(
+ UINT32 index,
+ __out_ecount_z(size) WCHAR* stringBuffer,
+ UINT32 size
+ ) PURE;
+};
+
+interface IDWriteFontFamily;
+interface IDWriteFont;
+
+/// <summary>
+/// The IDWriteFontCollection encapsulates a collection of fonts.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("a84cee02-3eea-4eee-a827-87c1a02a0fcc") IDWriteFontCollection : public IUnknown
+{
+ /// <summary>
+ /// Gets the number of font families in the collection.
+ /// </summary>
+ STDMETHOD_(UINT32, GetFontFamilyCount)() PURE;
+
+ /// <summary>
+ /// Creates a font family object given a zero-based font family index.
+ /// </summary>
+ /// <param name="index">Zero-based index of the font family.</param>
+ /// <param name="fontFamily">Receives a pointer the newly created font family object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontFamily)(
+ UINT32 index,
+ __out IDWriteFontFamily** fontFamily
+ ) PURE;
+
+ /// <summary>
+ /// Finds the font family with the specified family name.
+ /// </summary>
+ /// <param name="familyName">Name of the font family. The name is not case-sensitive but must otherwise exactly match a family name in the collection.</param>
+ /// <param name="index">Receives the zero-based index of the matching font family if the family name was found or UINT_MAX otherwise.</param>
+ /// <param name="exists">Receives TRUE if the family name exists or FALSE otherwise.</param>
+ /// <returns>
+ /// Standard HRESULT error code. If the specified family name does not exist, the return value is S_OK, but *index is UINT_MAX and *exists is FALSE.
+ /// </returns>
+ STDMETHOD(FindFamilyName)(
+ __in_z WCHAR const* familyName,
+ __out UINT32* index,
+ __out BOOL* exists
+ ) PURE;
+
+ /// <summary>
+ /// Gets the font object that corresponds to the same physical font as the specified font face object. The specified physical font must belong
+ /// to the font collection.
+ /// </summary>
+ /// <param name="fontFace">Font face object that specifies the physical font.</param>
+ /// <param name="font">Receives a pointer to the newly created font object if successful or NULL otherwise.</param>
+ /// <returns>
+ /// Standard HRESULT error code. If the specified physical font is not part of the font collection the return value is DWRITE_E_NOFONT.
+ /// </returns>
+ STDMETHOD(GetFontFromFontFace)(
+ IDWriteFontFace* fontFace,
+ __out IDWriteFont** font
+ ) PURE;
+};
+
+/// <summary>
+/// The IDWriteFontList interface represents a list of fonts.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("1a0d8438-1d97-4ec1-aef9-a2fb86ed6acb") IDWriteFontList : public IUnknown
+{
+ /// <summary>
+ /// Gets the font collection that contains the fonts.
+ /// </summary>
+ /// <param name="fontCollection">Receives a pointer to the font collection object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontCollection)(
+ __out IDWriteFontCollection** fontCollection
+ ) PURE;
+
+ /// <summary>
+ /// Gets the number of fonts in the font list.
+ /// </summary>
+ STDMETHOD_(UINT32, GetFontCount)() PURE;
+
+ /// <summary>
+ /// Gets a font given its zero-based index.
+ /// </summary>
+ /// <param name="index">Zero-based index of the font in the font list.</param>
+ /// <param name="font">Receives a pointer to the newly created font object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFont)(
+ UINT32 index,
+ __out IDWriteFont** font
+ ) PURE;
+};
+
+/// <summary>
+/// The IDWriteFontFamily interface represents a set of fonts that share the same design but are differentiated
+/// by weight, stretch, and style.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("da20d8ef-812a-4c43-9802-62ec4abd7add") IDWriteFontFamily : public IDWriteFontList
+{
+ /// <summary>
+ /// Creates an localized strings object that contains the family names for the font family, indexed by locale name.
+ /// </summary>
+ /// <param name="names">Receives a pointer to the newly created localized strings object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFamilyNames)(
+ __out IDWriteLocalizedStrings** names
+ ) PURE;
+
+ /// <summary>
+ /// Gets the font that best matches the specified properties.
+ /// </summary>
+ /// <param name="weight">Requested font weight.</param>
+ /// <param name="stretch">Requested font stretch.</param>
+ /// <param name="style">Requested font style.</param>
+ /// <param name="matchingFont">Receives a pointer to the newly created font object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFirstMatchingFont)(
+ DWRITE_FONT_WEIGHT weight,
+ DWRITE_FONT_STRETCH stretch,
+ DWRITE_FONT_STYLE style,
+ __out IDWriteFont** matchingFont
+ ) PURE;
+
+ /// <summary>
+ /// Gets a list of fonts in the font family ranked in order of how well they match the specified properties.
+ /// </summary>
+ /// <param name="weight">Requested font weight.</param>
+ /// <param name="stretch">Requested font stretch.</param>
+ /// <param name="style">Requested font style.</param>
+ /// <param name="matchingFonts">Receives a pointer to the newly created font list object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetMatchingFonts)(
+ DWRITE_FONT_WEIGHT weight,
+ DWRITE_FONT_STRETCH stretch,
+ DWRITE_FONT_STYLE style,
+ __out IDWriteFontList** matchingFonts
+ ) PURE;
+};
+
+/// <summary>
+/// The IDWriteFont interface represents a physical font in a font collection.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("acd16696-8c14-4f5d-877e-fe3fc1d32737") IDWriteFont : public IUnknown
+{
+ /// <summary>
+ /// Gets the font family to which the specified font belongs.
+ /// </summary>
+ /// <param name="fontFamily">Receives a pointer to the font family object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontFamily)(
+ __out IDWriteFontFamily** fontFamily
+ ) PURE;
+
+ /// <summary>
+ /// Gets the weight of the specified font.
+ /// </summary>
+ STDMETHOD_(DWRITE_FONT_WEIGHT, GetWeight)() PURE;
+
+ /// <summary>
+ /// Gets the stretch (aka. width) of the specified font.
+ /// </summary>
+ STDMETHOD_(DWRITE_FONT_STRETCH, GetStretch)() PURE;
+
+ /// <summary>
+ /// Gets the style (aka. slope) of the specified font.
+ /// </summary>
+ STDMETHOD_(DWRITE_FONT_STYLE, GetStyle)() PURE;
+
+ /// <summary>
+ /// Returns TRUE if the font is a symbol font or FALSE if not.
+ /// </summary>
+ STDMETHOD_(BOOL, IsSymbolFont)() PURE;
+
+ /// <summary>
+ /// Gets a localized strings collection containing the face names for the font (e.g., Regular or Bold), indexed by locale name.
+ /// </summary>
+ /// <param name="names">Receives a pointer to the newly created localized strings object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFaceNames)(
+ __out IDWriteLocalizedStrings** names
+ ) PURE;
+
+ /// <summary>
+ /// Gets a localized strings collection containing the specified informational strings, indexed by locale name.
+ /// </summary>
+ /// <param name="informationalStringID">Identifies the string to get.</param>
+ /// <param name="informationalStrings">Receives a pointer to the newly created localized strings object.</param>
+ /// <param name="exists">Receives the value TRUE if the font contains the specified string ID or FALSE if not.</param>
+ /// <returns>
+ /// Standard HRESULT error code. If the font does not contain the specified string, the return value is S_OK but
+ /// informationalStrings receives a NULL pointer and exists receives the value FALSE.
+ /// </returns>
+ STDMETHOD(GetInformationalStrings)(
+ DWRITE_INFORMATIONAL_STRING_ID informationalStringID,
+ __out IDWriteLocalizedStrings** informationalStrings,
+ __out BOOL* exists
+ ) PURE;
+
+ /// <summary>
+ /// Gets a value that indicates what simulation are applied to the specified font.
+ /// </summary>
+ STDMETHOD_(DWRITE_FONT_SIMULATIONS, GetSimulations)() PURE;
+
+ /// <summary>
+ /// Gets the metrics for the font.
+ /// </summary>
+ /// <param name="fontMetrics">Receives the font metrics.</param>
+ STDMETHOD_(void, GetMetrics)(
+ __out DWRITE_FONT_METRICS* fontMetrics
+ ) PURE;
+
+ /// <summary>
+ /// Determines whether the font supports the specified character.
+ /// </summary>
+ /// <param name="unicodeValue">Unicode (UCS-4) character value.</param>
+ /// <param name="exists">Receives the value TRUE if the font supports the specified character or FALSE if not.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(HasCharacter)(
+ UINT32 unicodeValue,
+ __out BOOL* exists
+ ) PURE;
+
+ /// <summary>
+ /// Creates a font face object for the font.
+ /// </summary>
+ /// <param name="fontFace">Receives a pointer to the newly created font face object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateFontFace)(
+ __out IDWriteFontFace** fontFace
+ ) PURE;
+};
+
+/// <summary>
+/// Direction for how reading progresses.
+/// </summary>
+enum DWRITE_READING_DIRECTION
+{
+ /// <summary>
+ /// Reading progresses from left to right.
+ /// </summary>
+ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT,
+
+ /// <summary>
+ /// Reading progresses from right to left.
+ /// </summary>
+ DWRITE_READING_DIRECTION_RIGHT_TO_LEFT
+};
+
+/// <summary>
+/// Direction for how lines of text are placed relative to one another.
+/// </summary>
+enum DWRITE_FLOW_DIRECTION
+{
+ /// <summary>
+ /// Text lines are placed from top to bottom.
+ /// </summary>
+ DWRITE_FLOW_DIRECTION_TOP_TO_BOTTOM
+};
+
+/// <summary>
+/// Alignment of paragraph text along the reading direction axis relative to
+/// the leading and trailing edge of the layout box.
+/// </summary>
+enum DWRITE_TEXT_ALIGNMENT
+{
+ /// <summary>
+ /// The leading edge of the paragraph text is aligned to the layout box's leading edge.
+ /// </summary>
+ DWRITE_TEXT_ALIGNMENT_LEADING,
+
+ /// <summary>
+ /// The trailing edge of the paragraph text is aligned to the layout box's trailing edge.
+ /// </summary>
+ DWRITE_TEXT_ALIGNMENT_TRAILING,
+
+ /// <summary>
+ /// The center of the paragraph text is aligned to the center of the layout box.
+ /// </summary>
+ DWRITE_TEXT_ALIGNMENT_CENTER
+};
+
+/// <summary>
+/// Alignment of paragraph text along the flow direction axis relative to the
+/// flow's beginning and ending edge of the layout box.
+/// </summary>
+enum DWRITE_PARAGRAPH_ALIGNMENT
+{
+ /// <summary>
+ /// The first line of paragraph is aligned to the flow's beginning edge of the layout box.
+ /// </summary>
+ DWRITE_PARAGRAPH_ALIGNMENT_NEAR,
+
+ /// <summary>
+ /// The last line of paragraph is aligned to the flow's ending edge of the layout box.
+ /// </summary>
+ DWRITE_PARAGRAPH_ALIGNMENT_FAR,
+
+ /// <summary>
+ /// The center of the paragraph is aligned to the center of the flow of the layout box.
+ /// </summary>
+ DWRITE_PARAGRAPH_ALIGNMENT_CENTER
+};
+
+/// <summary>
+/// Word wrapping in multiline paragraph.
+/// </summary>
+enum DWRITE_WORD_WRAPPING
+{
+ /// <summary>
+ /// Words are broken across lines to avoid text overflowing the layout box.
+ /// </summary>
+ DWRITE_WORD_WRAPPING_WRAP,
+
+ /// <summary>
+ /// Words are kept within the same line even when it overflows the layout box.
+ /// This option is often used with scrolling to reveal overflow text.
+ /// </summary>
+ DWRITE_WORD_WRAPPING_NO_WRAP
+};
+
+/// <summary>
+/// The method used for line spacing in layout.
+/// </summary>
+enum DWRITE_LINE_SPACING_METHOD
+{
+ /// <summary>
+ /// Line spacing depends solely on the content, growing to accomodate the size of fonts and inline objects.
+ /// </summary>
+ DWRITE_LINE_SPACING_METHOD_DEFAULT,
+
+ /// <summary>
+ /// Lines are explicitly set to uniform spacing, regardless of contained font sizes.
+ /// This can be useful to avoid the uneven appearance that can occur from font fallback.
+ /// </summary>
+ DWRITE_LINE_SPACING_METHOD_UNIFORM
+};
+
+/// <summary>
+/// Text granularity used to trim text overflowing the layout box.
+/// </summary>
+enum DWRITE_TRIMMING_GRANULARITY
+{
+ /// <summary>
+ /// No trimming occurs. Text flows beyond the layout width.
+ /// </summary>
+ DWRITE_TRIMMING_GRANULARITY_NONE,
+
+ /// <summary>
+ /// Trimming occurs at character cluster boundary.
+ /// </summary>
+ DWRITE_TRIMMING_GRANULARITY_CHARACTER,
+
+ /// <summary>
+ /// Trimming occurs at word boundary.
+ /// </summary>
+ DWRITE_TRIMMING_GRANULARITY_WORD
+};
+
+/// <summary>
+/// Typographic feature of text supplied by the font.
+/// </summary>
+enum DWRITE_FONT_FEATURE_TAG
+{
+ DWRITE_FONT_FEATURE_TAG_ALTERNATIVE_FRACTIONS = 0x63726661, // 'afrc'
+ DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS_FROM_CAPITALS = 0x63703263, // 'c2pc'
+ DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS_FROM_CAPITALS = 0x63733263, // 'c2sc'
+ DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_ALTERNATES = 0x746c6163, // 'calt'
+ DWRITE_FONT_FEATURE_TAG_CASE_SENSITIVE_FORMS = 0x65736163, // 'case'
+ DWRITE_FONT_FEATURE_TAG_GLYPH_COMPOSITION_DECOMPOSITION = 0x706d6363, // 'ccmp'
+ DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_LIGATURES = 0x67696c63, // 'clig'
+ DWRITE_FONT_FEATURE_TAG_CAPITAL_SPACING = 0x70737063, // 'cpsp'
+ DWRITE_FONT_FEATURE_TAG_CONTEXTUAL_SWASH = 0x68777363, // 'cswh'
+ DWRITE_FONT_FEATURE_TAG_CURSIVE_POSITIONING = 0x73727563, // 'curs'
+ DWRITE_FONT_FEATURE_TAG_DEFAULT = 0x746c6664, // 'dflt'
+ DWRITE_FONT_FEATURE_TAG_DISCRETIONARY_LIGATURES = 0x67696c64, // 'dlig'
+ DWRITE_FONT_FEATURE_TAG_EXPERT_FORMS = 0x74707865, // 'expt'
+ DWRITE_FONT_FEATURE_TAG_FRACTIONS = 0x63617266, // 'frac'
+ DWRITE_FONT_FEATURE_TAG_FULL_WIDTH = 0x64697766, // 'fwid'
+ DWRITE_FONT_FEATURE_TAG_HALF_FORMS = 0x666c6168, // 'half'
+ DWRITE_FONT_FEATURE_TAG_HALANT_FORMS = 0x6e6c6168, // 'haln'
+ DWRITE_FONT_FEATURE_TAG_ALTERNATE_HALF_WIDTH = 0x746c6168, // 'halt'
+ DWRITE_FONT_FEATURE_TAG_HISTORICAL_FORMS = 0x74736968, // 'hist'
+ DWRITE_FONT_FEATURE_TAG_HORIZONTAL_KANA_ALTERNATES = 0x616e6b68, // 'hkna'
+ DWRITE_FONT_FEATURE_TAG_HISTORICAL_LIGATURES = 0x67696c68, // 'hlig'
+ DWRITE_FONT_FEATURE_TAG_HALF_WIDTH = 0x64697768, // 'hwid'
+ DWRITE_FONT_FEATURE_TAG_HOJO_KANJI_FORMS = 0x6f6a6f68, // 'hojo'
+ DWRITE_FONT_FEATURE_TAG_JIS04_FORMS = 0x3430706a, // 'jp04'
+ DWRITE_FONT_FEATURE_TAG_JIS78_FORMS = 0x3837706a, // 'jp78'
+ DWRITE_FONT_FEATURE_TAG_JIS83_FORMS = 0x3338706a, // 'jp83'
+ DWRITE_FONT_FEATURE_TAG_JIS90_FORMS = 0x3039706a, // 'jp90'
+ DWRITE_FONT_FEATURE_TAG_KERNING = 0x6e72656b, // 'kern'
+ DWRITE_FONT_FEATURE_TAG_STANDARD_LIGATURES = 0x6167696c, // 'liga'
+ DWRITE_FONT_FEATURE_TAG_LINING_FIGURES = 0x6d756e6c, // 'lnum'
+ DWRITE_FONT_FEATURE_TAG_LOCALIZED_FORMS = 0x6c636f6c, // 'locl'
+ DWRITE_FONT_FEATURE_TAG_MARK_POSITIONING = 0x6b72616d, // 'mark'
+ DWRITE_FONT_FEATURE_TAG_MATHEMATICAL_GREEK = 0x6b72676d, // 'mgrk'
+ DWRITE_FONT_FEATURE_TAG_MARK_TO_MARK_POSITIONING = 0x6b6d6b6d, // 'mkmk'
+ DWRITE_FONT_FEATURE_TAG_ALTERNATE_ANNOTATION_FORMS = 0x746c616e, // 'nalt'
+ DWRITE_FONT_FEATURE_TAG_NLC_KANJI_FORMS = 0x6b636c6e, // 'nlck'
+ DWRITE_FONT_FEATURE_TAG_OLD_STYLE_FIGURES = 0x6d756e6f, // 'onum'
+ DWRITE_FONT_FEATURE_TAG_ORDINALS = 0x6e64726f, // 'ordn'
+ DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_ALTERNATE_WIDTH = 0x746c6170, // 'palt'
+ DWRITE_FONT_FEATURE_TAG_PETITE_CAPITALS = 0x70616370, // 'pcap'
+ DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_FIGURES = 0x6d756e70, // 'pnum'
+ DWRITE_FONT_FEATURE_TAG_PROPORTIONAL_WIDTHS = 0x64697770, // 'pwid'
+ DWRITE_FONT_FEATURE_TAG_QUARTER_WIDTHS = 0x64697771, // 'qwid'
+ DWRITE_FONT_FEATURE_TAG_REQUIRED_LIGATURES = 0x67696c72, // 'rlig'
+ DWRITE_FONT_FEATURE_TAG_RUBY_NOTATION_FORMS = 0x79627572, // 'ruby'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_ALTERNATES = 0x746c6173, // 'salt'
+ DWRITE_FONT_FEATURE_TAG_SCIENTIFIC_INFERIORS = 0x666e6973, // 'sinf'
+ DWRITE_FONT_FEATURE_TAG_SMALL_CAPITALS = 0x70636d73, // 'smcp'
+ DWRITE_FONT_FEATURE_TAG_SIMPLIFIED_FORMS = 0x6c706d73, // 'smpl'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_1 = 0x31307373, // 'ss01'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_2 = 0x32307373, // 'ss02'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_3 = 0x33307373, // 'ss03'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_4 = 0x34307373, // 'ss04'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_5 = 0x35307373, // 'ss05'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_6 = 0x36307373, // 'ss06'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_7 = 0x37307373, // 'ss07'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_8 = 0x38307373, // 'ss08'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_9 = 0x39307373, // 'ss09'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_10 = 0x30317373, // 'ss10'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_11 = 0x31317373, // 'ss11'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_12 = 0x32317373, // 'ss12'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_13 = 0x33317373, // 'ss13'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_14 = 0x34317373, // 'ss14'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_15 = 0x35317373, // 'ss15'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_16 = 0x36317373, // 'ss16'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_17 = 0x37317373, // 'ss17'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_18 = 0x38317373, // 'ss18'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_19 = 0x39317373, // 'ss19'
+ DWRITE_FONT_FEATURE_TAG_STYLISTIC_SET_20 = 0x30327373, // 'ss20'
+ DWRITE_FONT_FEATURE_TAG_SUBSCRIPT = 0x73627573, // 'subs'
+ DWRITE_FONT_FEATURE_TAG_SUPERSCRIPT = 0x73707573, // 'sups'
+ DWRITE_FONT_FEATURE_TAG_SWASH = 0x68737773, // 'swsh'
+ DWRITE_FONT_FEATURE_TAG_TITLING = 0x6c746974, // 'titl'
+ DWRITE_FONT_FEATURE_TAG_TRADITIONAL_NAME_FORMS = 0x6d616e74, // 'tnam'
+ DWRITE_FONT_FEATURE_TAG_TABULAR_FIGURES = 0x6d756e74, // 'tnum'
+ DWRITE_FONT_FEATURE_TAG_TRADITIONAL_FORMS = 0x64617274, // 'trad'
+ DWRITE_FONT_FEATURE_TAG_THIRD_WIDTHS = 0x64697774, // 'twid'
+ DWRITE_FONT_FEATURE_TAG_UNICASE = 0x63696e75, // 'unic'
+ DWRITE_FONT_FEATURE_TAG_SLASHED_ZERO = 0x6f72657a, // 'zero'
+};
+
+/// <summary>
+/// The DWRITE_TEXT_RANGE structure specifies a range of text positions where format is applied.
+/// </summary>
+struct DWRITE_TEXT_RANGE
+{
+ /// <summary>
+ /// The start text position of the range.
+ /// </summary>
+ UINT32 startPosition;
+
+ /// <summary>
+ /// The number of text positions in the range.
+ /// </summary>
+ UINT32 length;
+};
+
+/// <summary>
+/// The DWRITE_FONT_FEATURE structure specifies properties used to identify and execute typographic feature in the font.
+/// </summary>
+struct DWRITE_FONT_FEATURE
+{
+ /// <summary>
+ /// The feature OpenType name identifier.
+ /// </summary>
+ DWRITE_FONT_FEATURE_TAG nameTag;
+
+ /// <summary>
+ /// Execution parameter of the feature.
+ /// </summary>
+ /// <remarks>
+ /// The parameter should be non-zero to enable the feature. Once enabled, a feature can't be disabled again within
+ /// the same range. Features requiring a selector use this value to indicate the selector index.
+ /// </remarks>
+ UINT32 parameter;
+};
+
+/// <summary>
+/// Defines a set of typographic features to be applied during shaping.
+/// Notice the character range which this feature list spans is specified
+/// as a separate parameter to GetGlyphs.
+/// </summary>
+struct DWRITE_TYPOGRAPHIC_FEATURES
+{
+ /// <summary>
+ /// Array of font features.
+ /// </summary>
+ __field_ecount(featureCount) DWRITE_FONT_FEATURE* features;
+
+ /// <summary>
+ /// The number of features.
+ /// </summary>
+ UINT32 featureCount;
+};
+
+/// <summary>
+/// The DWRITE_TRIMMING structure specifies the trimming option for text overflowing the layout box.
+/// </summary>
+struct DWRITE_TRIMMING
+{
+ /// <summary>
+ /// Text granularity of which trimming applies.
+ /// </summary>
+ DWRITE_TRIMMING_GRANULARITY granularity;
+
+ /// <summary>
+ /// Character code used as the delimiter signaling the beginning of the portion of text to be preserved,
+ /// most useful for path ellipsis, where the delimeter would be a slash.
+ /// </summary>
+ UINT32 delimiter;
+
+ /// <summary>
+ /// How many occurences of the delimiter to step back.
+ /// </summary>
+ UINT32 delimiterCount;
+};
+
+
+interface IDWriteTypography;
+interface IDWriteInlineObject;
+
+/// <summary>
+/// The format of text used for text layout purpose.
+/// </summary>
+/// <remarks>
+/// This object may not be thread-safe and it may carry the state of text format change.
+/// </remarks>
+interface DWRITE_DECLARE_INTERFACE("9c906818-31d7-4fd3-a151-7c5e225db55a") IDWriteTextFormat : public IUnknown
+{
+ /// <summary>
+ /// Set alignment option of text relative to layout box's leading and trailing edge.
+ /// </summary>
+ /// <param name="textAlignment">Text alignment option</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetTextAlignment)(
+ DWRITE_TEXT_ALIGNMENT textAlignment
+ ) PURE;
+
+ /// <summary>
+ /// Set alignment option of paragraph relative to layout box's top and bottom edge.
+ /// </summary>
+ /// <param name="paragraphAlignment">Paragraph alignment option</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetParagraphAlignment)(
+ DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment
+ ) PURE;
+
+ /// <summary>
+ /// Set word wrapping option.
+ /// </summary>
+ /// <param name="wordWrapping">Word wrapping option</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetWordWrapping)(
+ DWRITE_WORD_WRAPPING wordWrapping
+ ) PURE;
+
+ /// <summary>
+ /// Set paragraph reading direction.
+ /// </summary>
+ /// <param name="readingDirection">Text reading direction</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetReadingDirection)(
+ DWRITE_READING_DIRECTION readingDirection
+ ) PURE;
+
+ /// <summary>
+ /// Set paragraph flow direction.
+ /// </summary>
+ /// <param name="flowDirection">Paragraph flow direction</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetFlowDirection)(
+ DWRITE_FLOW_DIRECTION flowDirection
+ ) PURE;
+
+ /// <summary>
+ /// Set incremental tab stop position.
+ /// </summary>
+ /// <param name="incrementalTabStop">The incremental tab stop value</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetIncrementalTabStop)(
+ FLOAT incrementalTabStop
+ ) PURE;
+
+ /// <summary>
+ /// Set trimming options for any trailing text exceeding the layout width
+ /// or for any far text exceeding the layout height.
+ /// </summary>
+ /// <param name="trimmingOptions">Text trimming options.</param>
+ /// <param name="trimmingSign">Application-defined omission sign. This parameter may be NULL if no trimming sign is desired.</param>
+ /// <remarks>
+ /// Any inline object can be used for the trimming sign, but CreateEllipsisTrimmingSign
+ /// provides a typical ellipsis symbol. Trimming is also useful vertically for hiding
+ /// partial lines.
+ /// </remarks>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetTrimming)(
+ __in DWRITE_TRIMMING const* trimmingOptions,
+ IDWriteInlineObject* trimmingSign
+ ) PURE;
+
+ /// <summary>
+ /// Set line spacing.
+ /// </summary>
+ /// <param name="lineSpacingMethod">How to determine line height.</param>
+ /// <param name="lineSpacing">The line height, or rather distance between one baseline to another.</param>
+ /// <param name="baseline">Distance from top of line to baseline. A reasonable ratio to lineSpacing is 80%.</param>
+ /// <remarks>
+ /// For the default method, spacing depends solely on the content.
+ /// For uniform spacing, the given line height will override the content.
+ /// </remarks>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetLineSpacing)(
+ DWRITE_LINE_SPACING_METHOD lineSpacingMethod,
+ FLOAT lineSpacing,
+ FLOAT baseline
+ ) PURE;
+
+ /// <summary>
+ /// Get alignment option of text relative to layout box's leading and trailing edge.
+ /// </summary>
+ STDMETHOD_(DWRITE_TEXT_ALIGNMENT, GetTextAlignment)() PURE;
+
+ /// <summary>
+ /// Get alignment option of paragraph relative to layout box's top and bottom edge.
+ /// </summary>
+ STDMETHOD_(DWRITE_PARAGRAPH_ALIGNMENT, GetParagraphAlignment)() PURE;
+
+ /// <summary>
+ /// Get word wrapping option.
+ /// </summary>
+ STDMETHOD_(DWRITE_WORD_WRAPPING, GetWordWrapping)() PURE;
+
+ /// <summary>
+ /// Get paragraph reading direction.
+ /// </summary>
+ STDMETHOD_(DWRITE_READING_DIRECTION, GetReadingDirection)() PURE;
+
+ /// <summary>
+ /// Get paragraph flow direction.
+ /// </summary>
+ STDMETHOD_(DWRITE_FLOW_DIRECTION, GetFlowDirection)() PURE;
+
+ /// <summary>
+ /// Get incremental tab stop position.
+ /// </summary>
+ STDMETHOD_(FLOAT, GetIncrementalTabStop)() PURE;
+
+ /// <summary>
+ /// Get trimming options for text overflowing the layout width.
+ /// </summary>
+ /// <param name="trimmingOptions">Text trimming options.</param>
+ /// <param name="trimmingSign">Trimming omission sign. This parameter may be NULL.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetTrimming)(
+ __out DWRITE_TRIMMING* trimmingOptions,
+ __out IDWriteInlineObject** trimmingSign
+ ) PURE;
+
+ /// <summary>
+ /// Get line spacing.
+ /// </summary>
+ /// <param name="lineSpacingMethod">How line height is determined.</param>
+ /// <param name="lineSpacing">The line height, or rather distance between one baseline to another.</param>
+ /// <param name="baseline">Distance from top of line to baseline.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetLineSpacing)(
+ __out DWRITE_LINE_SPACING_METHOD* lineSpacingMethod,
+ __out FLOAT* lineSpacing,
+ __out FLOAT* baseline
+ ) PURE;
+
+ /// <summary>
+ /// Get the font collection.
+ /// </summary>
+ /// <param name="fontCollection">The current font collection.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontCollection)(
+ __out IDWriteFontCollection** fontCollection
+ ) PURE;
+
+ /// <summary>
+ /// Get the length of the font family name, in characters, not including the terminating NULL character.
+ /// </summary>
+ STDMETHOD_(UINT32, GetFontFamilyNameLength)() PURE;
+
+ /// <summary>
+ /// Get a copy of the font family name.
+ /// </summary>
+ /// <param name="fontFamilyName">Character array that receives the current font family name</param>
+ /// <param name="nameSize">Size of the character array in character count including the terminated NULL character.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontFamilyName)(
+ __out_ecount_z(nameSize) WCHAR* fontFamilyName,
+ UINT32 nameSize
+ ) PURE;
+
+ /// <summary>
+ /// Get the font weight.
+ /// </summary>
+ STDMETHOD_(DWRITE_FONT_WEIGHT, GetFontWeight)() PURE;
+
+ /// <summary>
+ /// Get the font style.
+ /// </summary>
+ STDMETHOD_(DWRITE_FONT_STYLE, GetFontStyle)() PURE;
+
+ /// <summary>
+ /// Get the font stretch.
+ /// </summary>
+ STDMETHOD_(DWRITE_FONT_STRETCH, GetFontStretch)() PURE;
+
+ /// <summary>
+ /// Get the font em height.
+ /// </summary>
+ STDMETHOD_(FLOAT, GetFontSize)() PURE;
+
+ /// <summary>
+ /// Get the length of the locale name, in characters, not including the terminating NULL character.
+ /// </summary>
+ STDMETHOD_(UINT32, GetLocaleNameLength)() PURE;
+
+ /// <summary>
+ /// Get a copy of the locale name.
+ /// </summary>
+ /// <param name="localeName">Character array that receives the current locale name</param>
+ /// <param name="nameSize">Size of the character array in character count including the terminated NULL character.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetLocaleName)(
+ __out_ecount_z(nameSize) WCHAR* localeName,
+ UINT32 nameSize
+ ) PURE;
+};
+
+
+/// <summary>
+/// Font typography setting.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("55f1112b-1dc2-4b3c-9541-f46894ed85b6") IDWriteTypography : public IUnknown
+{
+ /// <summary>
+ /// Add font feature.
+ /// </summary>
+ /// <param name="fontFeature">The font feature to add.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(AddFontFeature)(
+ DWRITE_FONT_FEATURE fontFeature
+ ) PURE;
+
+ /// <summary>
+ /// Get the number of font features.
+ /// </summary>
+ STDMETHOD_(UINT32, GetFontFeatureCount)() PURE;
+
+ /// <summary>
+ /// Get the font feature at the specified index.
+ /// </summary>
+ /// <param name="fontFeatureIndex">The zero-based index of the font feature to get.</param>
+ /// <param name="fontFeature">The font feature.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontFeature)(
+ UINT32 fontFeatureIndex,
+ __out DWRITE_FONT_FEATURE* fontFeature
+ ) PURE;
+};
+
+enum DWRITE_SCRIPT_SHAPES
+{
+ /// <summary>
+ /// No additional shaping requirement. Text is shaped with the writing system default behavior.
+ /// </summary>
+ DWRITE_SCRIPT_SHAPES_DEFAULT = 0,
+
+ /// <summary>
+ /// Text should leave no visual on display i.e. control or format control characters.
+ /// </summary>
+ DWRITE_SCRIPT_SHAPES_NO_VISUAL = 1
+};
+
+#ifdef DEFINE_ENUM_FLAG_OPERATORS
+DEFINE_ENUM_FLAG_OPERATORS(DWRITE_SCRIPT_SHAPES);
+#endif
+
+/// <summary>
+/// Association of text and its writing system script as well as some display attributes.
+/// </summary>
+struct DWRITE_SCRIPT_ANALYSIS
+{
+ /// <summary>
+ /// Zero-based index representation of writing system script.
+ /// </summary>
+ UINT16 script;
+
+ /// <summary>
+ /// Additional shaping requirement of text.
+ /// </summary>
+ DWRITE_SCRIPT_SHAPES shapes;
+};
+
+/// <summary>
+/// Condition at the edges of inline object or text used to determine
+/// line-breaking behavior.
+/// </summary>
+enum DWRITE_BREAK_CONDITION
+{
+ /// <summary>
+ /// Whether a break is allowed is determined by the condition of the
+ /// neighboring text span or inline object.
+ /// </summary>
+ DWRITE_BREAK_CONDITION_NEUTRAL,
+
+ /// <summary>
+ /// A break is allowed, unless overruled by the condition of the
+ /// neighboring text span or inline object, either prohibited by a
+ /// May Not or forced by a Must.
+ /// </summary>
+ DWRITE_BREAK_CONDITION_CAN_BREAK,
+
+ /// <summary>
+ /// There should be no break, unless overruled by a Must condition from
+ /// the neighboring text span or inline object.
+ /// </summary>
+ DWRITE_BREAK_CONDITION_MAY_NOT_BREAK,
+
+ /// <summary>
+ /// The break must happen, regardless of the condition of the adjacent
+ /// text span or inline object.
+ /// </summary>
+ DWRITE_BREAK_CONDITION_MUST_BREAK
+};
+
+/// <summary>
+/// Line breakpoint characteristics of a character.
+/// </summary>
+struct DWRITE_LINE_BREAKPOINT
+{
+ /// <summary>
+ /// Breaking condition before the character.
+ /// </summary>
+ UINT8 breakConditionBefore : 2;
+
+ /// <summary>
+ /// Breaking condition after the character.
+ /// </summary>
+ UINT8 breakConditionAfter : 2;
+
+ /// <summary>
+ /// The character is some form of whitespace, which may be meaningful
+ /// for justification.
+ /// </summary>
+ UINT8 isWhitespace : 1;
+
+ /// <summary>
+ /// The character is a soft hyphen, often used to indicate hyphenation
+ /// points inside words.
+ /// </summary>
+ UINT8 isSoftHyphen : 1;
+
+ UINT8 padding : 2;
+};
+
+/// <summary>
+/// How to apply number substitution on digits and related punctuation.
+/// </summary>
+enum DWRITE_NUMBER_SUBSTITUTION_METHOD
+{
+ /// <summary>
+ /// Specifies that the substitution method should be determined based
+ /// on LOCALE_IDIGITSUBSTITUTION value of the specified text culture.
+ /// </summary>
+ DWRITE_NUMBER_SUBSTITUTION_METHOD_FROM_CULTURE,
+
+ /// <summary>
+ /// If the culture is Arabic or Farsi, specifies that the number shape
+ /// depend on the context. Either traditional or nominal number shape
+ /// are used depending on the nearest preceding strong character or (if
+ /// there is none) the reading direction of the paragraph.
+ /// </summary>
+ DWRITE_NUMBER_SUBSTITUTION_METHOD_CONTEXTUAL,
+
+ /// <summary>
+ /// Specifies that code points 0x30-0x39 are always rendered as nominal numeral
+ /// shapes (ones of the European number), i.e., no substitution is performed.
+ /// </summary>
+ DWRITE_NUMBER_SUBSTITUTION_METHOD_NONE,
+
+ /// <summary>
+ /// Specifies that number are rendered using the national number shape
+ /// as specified by the LOCALE_SNATIVEDIGITS value of the specified text culture.
+ /// </summary>
+ DWRITE_NUMBER_SUBSTITUTION_METHOD_NATIONAL,
+
+ /// <summary>
+ /// Specifies that number are rendered using the traditional shape
+ /// for the specified culture. For most cultures, this is the same as
+ /// NativeNational. However, NativeNational results in Latin number
+ /// for some Arabic cultures, whereas this value results in Arabic
+ /// number for all Arabic cultures.
+ /// </summary>
+ DWRITE_NUMBER_SUBSTITUTION_METHOD_TRADITIONAL
+};
+
+/// <summary>
+/// Holds the appropriate digits and numeric punctuation for a given locale.
+/// </summary>
+interface DECLSPEC_UUID("14885CC9-BAB0-4f90-B6ED-5C366A2CD03D") DECLSPEC_NOVTABLE IDWriteNumberSubstitution : public IUnknown
+{
+};
+
+/// <summary>
+/// Shaping output properties per input character.
+/// </summary>
+struct DWRITE_SHAPING_TEXT_PROPERTIES
+{
+ /// <summary>
+ /// This character can be shaped independently from the others
+ /// (usually set for the space character).
+ /// </summary>
+ UINT16 isShapedAlone : 1;
+
+ /// <summary>
+ /// Reserved for use by shaping engine.
+ /// </summary>
+ UINT16 reserved : 15;
+};
+
+/// <summary>
+/// Shaping output properties per output glyph.
+/// </summary>
+struct DWRITE_SHAPING_GLYPH_PROPERTIES
+{
+ /// <summary>
+ /// Justification class, whether to use spacing, kashidas, or
+ /// another method. This exists for backwards compatibility
+ /// with Uniscribe's SCRIPT_JUSTIFY enum.
+ /// </summary>
+ UINT16 justification : 4;
+
+ /// <summary>
+ /// Indicates glyph is the first of a cluster.
+ /// </summary>
+ UINT16 isClusterStart : 1;
+
+ /// <summary>
+ /// Glyph is a diacritic.
+ /// </summary>
+ UINT16 isDiacritic : 1;
+
+ /// <summary>
+ /// Glyph has no width, blank, ZWJ, ZWNJ etc.
+ /// </summary>
+ UINT16 isZeroWidthSpace : 1;
+
+ /// <summary>
+ /// Reserved for use by shaping engine.
+ /// </summary>
+ UINT16 reserved : 9;
+};
+
+/// <summary>
+/// The interface implemented by the text analyzer's client to provide text to
+/// the analyzer. It allows the separation between the logical view of text as
+/// a continuous stream of characters identifiable by unique text positions,
+/// and the actual memory layout of potentially discrete blocks of text in the
+/// client's backing store.
+///
+/// If any of these callbacks returns an error, the analysis functions will
+/// stop prematurely and return a callback error. Rather than return E_NOTIMPL,
+/// an application should stub the method and return a constant/null and S_OK.
+/// </summary>
+interface DECLSPEC_UUID("688e1a58-5094-47c8-adc8-fbcea60ae92b") DECLSPEC_NOVTABLE IDWriteTextAnalysisSource : public IUnknown
+{
+ /// <summary>
+ /// Get a block of text starting at the specified text position.
+ /// Returning NULL indicates the end of text - the position is after
+ /// the last character. This function is called iteratively for
+ /// each consecutive block, tying together several fragmented blocks
+ /// in the backing store into a virtual contiguous string.
+ /// </summary>
+ /// <param name="textPosition">First position of the piece to obtain. All
+ /// positions are in UTF16 code-units, not whole characters, which
+ /// matters when supplementary characters are used.</param>
+ /// <param name="textString">Address that receives a pointer to the text block
+ /// at the specified position.</param>
+ /// <param name="textLength">Number of UTF16 units of the retrieved chunk.
+ /// The returned length is not the length of the block, but the length
+ /// remaining in the block, from the given position until its end.
+ /// So querying for a position that is 75 positions into a 100
+ /// postition block would return 25.</param>
+ /// <returns>Pointer to the first character at the given text position.
+ /// NULL indicates no chunk available at the specified position, either
+ /// because textPosition >= the entire text content length or because the
+ /// queried position is not mapped into the app's backing store.</returns>
+ /// <remarks>
+ /// Although apps can implement sparse textual content that only maps part of
+ /// the backing store, the app must map any text that is in the range passed
+ /// to any analysis functions.
+ /// </remarks>
+ STDMETHOD(GetTextAtPosition)(
+ UINT32 textPosition,
+ __out WCHAR const** textString,
+ __out UINT32* textLength
+ ) PURE;
+
+ /// <summary>
+ /// Get a block of text immediately preceding the specified position.
+ /// </summary>
+ /// <param name="textPosition">Position immediately after the last position of the chunk to obtain.</param>
+ /// <param name="textString">Address that receives a pointer to the text block
+ /// at the specified position.</param>
+ /// <param name="textLength">Number of UTF16 units of the retrieved block.
+ /// The length returned is from the given position to the front of
+ /// the block.</param>
+ /// <returns>Pointer to the first character at (textPosition - textLength).
+ /// NULL indicates no chunk available at the specified position, either
+ /// because textPosition == 0,the textPosition > the entire text content
+ /// length, or the queried position is not mapped into the app's backing
+ /// store.</returns>
+ /// <remarks>
+ /// Although apps can implement sparse textual content that only maps part of
+ /// the backing store, the app must map any text that is in the range passed
+ /// to any analysis functions.
+ /// </remarks>
+ STDMETHOD(GetTextBeforePosition)(
+ UINT32 textPosition,
+ __out WCHAR const** textString,
+ __out UINT32* textLength
+ ) PURE;
+
+ /// <summary>
+ /// Get paragraph reading direction.
+ /// </summary>
+ STDMETHOD_(DWRITE_READING_DIRECTION, GetParagraphReadingDirection)() PURE;
+
+ /// <summary>
+ /// Get locale name on the range affected by it.
+ /// </summary>
+ /// <param name="textPosition">Position to get the locale name of.</param>
+ /// <param name="textLength">Receives the length from the given position up to the
+ /// next differing locale.</param>
+ /// <param name="localeName">Address that receives a pointer to the locale
+ /// at the specified position.</param>
+ /// <remarks>
+ /// The localeName pointer must remain valid until the next call or until
+ /// the analysis returns.
+ /// </remarks>
+ STDMETHOD(GetLocaleName)(
+ UINT32 textPosition,
+ __out UINT32* textLength,
+ __out_z WCHAR const** localeName
+ ) PURE;
+
+ /// <summary>
+ /// Get number substitution on the range affected by it.
+ /// </summary>
+ /// <param name="textPosition">Position to get the number substitution of.</param>
+ /// <param name="textLength">Receives the length from the given position up to the
+ /// next differing number substitution.</param>
+ /// <param name="numberSubstitution">Address that receives a pointer to the number substitution
+ /// at the specified position.</param>
+ /// <remarks>
+ /// Any implementation should return the number substitution with an
+ /// incremented ref count, and the analysis will release when finished
+ /// with it (either before the next call or before it returns). However,
+ /// the sink callback may hold onto it after that.
+ /// </remarks>
+ STDMETHOD(GetNumberSubstitution)(
+ UINT32 textPosition,
+ __out UINT32* textLength,
+ __out IDWriteNumberSubstitution** numberSubstitution
+ ) PURE;
+};
+
+/// <summary>
+/// The interface implemented by the text analyzer's client to receive the
+/// output of a given text analysis. The Text analyzer disregards any current
+/// state of the analysis sink, therefore a Set method call on a range
+/// overwrites the previously set analysis result of the same range.
+/// </summary>
+interface DECLSPEC_UUID("5810cd44-0ca0-4701-b3fa-bec5182ae4f6") DECLSPEC_NOVTABLE IDWriteTextAnalysisSink : public IUnknown
+{
+ /// <summary>
+ /// Report script analysis for the text range.
+ /// </summary>
+ /// <param name="textPosition">Starting position to report from.</param>
+ /// <param name="textLength">Number of UTF16 units of the reported range.</param>
+ /// <param name="scriptAnalysis">Script analysis of characters in range.</param>
+ /// <returns>
+ /// A successful code or error code to abort analysis.
+ /// </returns>
+ STDMETHOD(SetScriptAnalysis)(
+ UINT32 textPosition,
+ UINT32 textLength,
+ __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis
+ ) PURE;
+
+ /// <summary>
+ /// Repport line-break opportunities for each character, starting from
+ /// the specified position.
+ /// </summary>
+ /// <param name="textPosition">Starting position to report from.</param>
+ /// <param name="textLength">Number of UTF16 units of the reported range.</param>
+ /// <param name="lineBreakpoints">Breaking conditions for each character.</param>
+ /// <returns>
+ /// A successful code or error code to abort analysis.
+ /// </returns>
+ STDMETHOD(SetLineBreakpoints)(
+ UINT32 textPosition,
+ UINT32 textLength,
+ __in_ecount(textLength) DWRITE_LINE_BREAKPOINT const* lineBreakpoints
+ ) PURE;
+
+ /// <summary>
+ /// Set bidirectional level on the range, called once per each
+ /// level run change (either explicit or resolved implicit).
+ /// </summary>
+ /// <param name="textPosition">Starting position to report from.</param>
+ /// <param name="textLength">Number of UTF16 units of the reported range.</param>
+ /// <param name="explicitLevel">Explicit level from embedded control codes
+ /// RLE/RLO/LRE/LRO/PDF, determined before any additional rules.</param>
+ /// <param name="resolvedLevel">Final implicit level considering the
+ /// explicit level and characters' natural directionality, after all
+ /// Bidi rules have been applied.</param>
+ /// <returns>
+ /// A successful code or error code to abort analysis.
+ /// </returns>
+ STDMETHOD(SetBidiLevel)(
+ UINT32 textPosition,
+ UINT32 textLength,
+ UINT8 explicitLevel,
+ UINT8 resolvedLevel
+ ) PURE;
+
+ /// <summary>
+ /// Set number substitution on the range.
+ /// </summary>
+ /// <param name="textPosition">Starting position to report from.</param>
+ /// <param name="textLength">Number of UTF16 units of the reported range.</param>
+ /// <param name="numberSubstitution">The number substitution applicable to
+ /// the returned range of text. The sink callback may hold onto it by
+ /// incrementing its ref count.</param>
+ /// <returns>
+ /// A successful code or error code to abort analysis.
+ /// </returns>
+ /// <remark>
+ /// Unlike script and bidi analysis, where every character passed to the
+ /// analyzer has a result, this will only be called for those ranges where
+ /// substitution is applicable. For any other range, you will simply not
+ /// be called.
+ /// </remark>
+ STDMETHOD(SetNumberSubstitution)(
+ UINT32 textPosition,
+ UINT32 textLength,
+ __notnull IDWriteNumberSubstitution* numberSubstitution
+ ) PURE;
+};
+
+/// <summary>
+/// Analyzes various text properties for complex script processing.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("b7e6163e-7f46-43b4-84b3-e4e6249c365d") IDWriteTextAnalyzer : public IUnknown
+{
+ /// <summary>
+ /// Analyzes a text range for script boundaries, reading text attributes
+ /// from the source and reporting the Unicode script ID to the sink
+ /// callback SetScript.
+ /// </summary>
+ /// <param name="analysisSource">Source object to analyze.</param>
+ /// <param name="textPosition">Starting position within the source object.</param>
+ /// <param name="textLength">Length to analyze.</param>
+ /// <param name="analysisSink">Callback object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(AnalyzeScript)(
+ IDWriteTextAnalysisSource* analysisSource,
+ UINT32 textPosition,
+ UINT32 textLength,
+ IDWriteTextAnalysisSink* analysisSink
+ ) PURE;
+
+ /// <summary>
+ /// Analyzes a text range for script directionality, reading attributes
+ /// from the source and reporting levels to the sink callback SetBidiLevel.
+ /// </summary>
+ /// <param name="analysisSource">Source object to analyze.</param>
+ /// <param name="textPosition">Starting position within the source object.</param>
+ /// <param name="textLength">Length to analyze.</param>
+ /// <param name="analysisSink">Callback object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// While the function can handle multiple paragraphs, the text range
+ /// should not arbitrarily split the middle of paragraphs. Otherwise the
+ /// returned levels may be wrong, since the Bidi algorithm is meant to
+ /// apply to the paragraph as a whole.
+ /// </remarks>
+ /// <remarks>
+ /// Embedded control codes (LRE/LRO/RLE/RLO/PDF) are taken into account.
+ /// </remarks>
+ STDMETHOD(AnalyzeBidi)(
+ IDWriteTextAnalysisSource* analysisSource,
+ UINT32 textPosition,
+ UINT32 textLength,
+ IDWriteTextAnalysisSink* analysisSink
+ ) PURE;
+
+ /// <summary>
+ /// Analyzes a text range for spans where number substitution is applicable,
+ /// reading attributes from the source and reporting substitutable ranges
+ /// to the sink callback SetNumberSubstitution.
+ /// </summary>
+ /// <param name="analysisSource">Source object to analyze.</param>
+ /// <param name="textPosition">Starting position within the source object.</param>
+ /// <param name="textLength">Length to analyze.</param>
+ /// <param name="analysisSink">Callback object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// While the function can handle multiple ranges of differing number
+ /// substitutions, the text ranges should not arbitrarily split the
+ /// middle of numbers. Otherwise it will treat the numbers separately
+ /// and will not translate any intervening punctuation.
+ /// </remarks>
+ /// <remarks>
+ /// Embedded control codes (LRE/LRO/RLE/RLO/PDF) are taken into account.
+ /// </remarks>
+ STDMETHOD(AnalyzeNumberSubstitution)(
+ IDWriteTextAnalysisSource* analysisSource,
+ UINT32 textPosition,
+ UINT32 textLength,
+ IDWriteTextAnalysisSink* analysisSink
+ ) PURE;
+
+ /// <summary>
+ /// Analyzes a text range for potential breakpoint opportunities, reading
+ /// attributes from the source and reporting breakpoint opportunities to
+ /// the sink callback SetLineBreakpoints.
+ /// </summary>
+ /// <param name="analysisSource">Source object to analyze.</param>
+ /// <param name="textPosition">Starting position within the source object.</param>
+ /// <param name="textLength">Length to analyze.</param>
+ /// <param name="analysisSink">Callback object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// While the function can handle multiple paragraphs, the text range
+ /// should not arbitrarily split the middle of paragraphs, unless the
+ /// given text span is considered a whole unit. Otherwise the
+ /// returned properties for the first and last characters will
+ /// inappropriately allow breaks.
+ /// </remarks>
+ /// <remarks>
+ /// Special cases include the first, last, and surrogate characters. Any
+ /// text span is treated as if adjacent to inline objects on either side.
+ /// So the rules with contingent-break opportunities are used, where the
+ /// edge between text and inline objects is always treated as a potential
+ /// break opportunity, dependent on any overriding rules of the adjacent
+ /// objects to prohibit or force the break (see Unicode TR #14).
+ /// Surrogate pairs never break between.
+ /// </remarks>
+ STDMETHOD(AnalyzeLineBreakpoints)(
+ IDWriteTextAnalysisSource* analysisSource,
+ UINT32 textPosition,
+ UINT32 textLength,
+ IDWriteTextAnalysisSink* analysisSink
+ ) PURE;
+
+ /// <summary>
+ /// Parses the input text string and maps it to the set of glyphs and associated glyph data
+ /// according to the font and the writing system's rendering rules.
+ /// </summary>
+ /// <param name="textString">The string to convert to glyphs.</param>
+ /// <param name="textLength">The length of textString.</param>
+ /// <param name="fontFace">The font face to get glyphs from.</param>
+ /// <param name="isSideways">Set to true if the text is intended to be
+ /// drawn vertically.</param>
+ /// <param name="isRightToLeft">Set to TRUE for right-to-left text.</param>
+ /// <param name="scriptAnalysis">Script analysis result from AnalyzeScript.</param>
+ /// <param name="localeName">The locale to use when selecting glyphs.
+ /// e.g. the same character may map to different glyphs for ja-jp vs zh-chs.
+ /// If this is NULL then the default mapping based on the script is used.</param>
+ /// <param name="numberSubstitution">Optional number substitution which
+ /// selects the appropriate glyphs for digits and related numeric characters,
+ /// depending on the results obtained from AnalyzeNumberSubstitution. Passing
+ /// null indicates that no substitution is needed and that the digits should
+ /// receive nominal glyphs.</param>
+ /// <param name="features">An array of pointers to the sets of typographic
+ /// features to use in each feature range.</param>
+ /// <param name="featureRangeLengths">The length of each feature range, in characters.
+ /// The sum of all lengths should be equal to textLength.</param>
+ /// <param name="featureRanges">The number of feature ranges.</param>
+ /// <param name="maxGlyphCount">The maximum number of glyphs that can be
+ /// returned.</param>
+ /// <param name="clusterMap">The mapping from character ranges to glyph
+ /// ranges.</param>
+ /// <param name="textProps">Per-character output properties.</param>
+ /// <param name="glyphIndices">Output glyph indices.</param>
+ /// <param name="glyphProps">Per-glyph output properties.</param>
+ /// <param name="actualGlyphCount">The actual number of glyphs returned if
+ /// the call succeeds.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// Note that the mapping from characters to glyphs is, in general, many-
+ /// to-many. The recommended estimate for the per-glyph output buffers is
+ /// (3 * textLength / 2 + 16). This is not guaranteed to be sufficient.
+ ///
+ /// The value of the actualGlyphCount parameter is only valid if the call
+ /// succeeds. In the event that maxGlyphCount is not big enough
+ /// E_NOT_SUFFICIENT_BUFFER, which is equivalent to HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
+ /// will be returned. The application should allocate a larger buffer and try again.
+ /// </remarks>
+ STDMETHOD(GetGlyphs)(
+ __in_ecount(textLength) WCHAR const* textString,
+ UINT32 textLength,
+ IDWriteFontFace* fontFace,
+ BOOL isSideways,
+ BOOL isRightToLeft,
+ __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
+ __in_z_opt WCHAR const* localeName,
+ __maybenull IDWriteNumberSubstitution* numberSubstitution,
+ __in_ecount_opt(featureRanges) DWRITE_TYPOGRAPHIC_FEATURES const** features,
+ __in_ecount_opt(featureRanges) UINT32 const* featureRangeLengths,
+ UINT32 featureRanges,
+ UINT32 maxGlyphCount,
+ __out_ecount(textLength) UINT16* clusterMap,
+ __out_ecount(textLength) DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
+ __out_ecount(maxGlyphCount) UINT16* glyphIndices,
+ __out_ecount(maxGlyphCount) DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProps,
+ __out UINT32* actualGlyphCount
+ ) PURE;
+
+ /// <summary>
+ /// Place glyphs output from the GetGlyphs method according to the font
+ /// and the writing system's rendering rules.
+ /// </summary>
+ /// <param name="textString">The original string the glyphs came from.</param>
+ /// <param name="clusterMap">The mapping from character ranges to glyph
+ /// ranges. Returned by GetGlyphs.</param>
+ /// <param name="textProps">Per-character properties. Returned by
+ /// GetGlyphs.</param>
+ /// <param name="textLength">The length of textString.</param>
+ /// <param name="glyphIndices">Glyph indices. See GetGlyphs</param>
+ /// <param name="glyphProps">Per-glyph properties. See GetGlyphs</param>
+ /// <param name="glyphCount">The number of glyphs.</param>
+ /// <param name="fontFace">The font face the glyphs came from.</param>
+ /// <param name="fontEmSize">Logical font size in DIP's.</param>
+ /// <param name="isSideways">Set to true if the text is intended to be
+ /// drawn vertically.</param>
+ /// <param name="isRightToLeft">Set to TRUE for right-to-left text.</param>
+ /// <param name="scriptAnalysis">Script analysis result from AnalyzeScript.</param>
+ /// <param name="localeName">The locale to use when selecting glyphs.
+ /// e.g. the same character may map to different glyphs for ja-jp vs zh-chs.
+ /// If this is NULL then the default mapping based on the script is used.</param>
+ /// <param name="features">An array of pointers to the sets of typographic
+ /// features to use in each feature range.</param>
+ /// <param name="featureRangeLengths">The length of each feature range, in characters.
+ /// The sum of all lengths should be equal to textLength.</param>
+ /// <param name="featureRanges">The number of feature ranges.</param>
+ /// <param name="glyphAdvances">The advance width of each glyph.</param>
+ /// <param name="glyphOffsets">The offset of the origin of each glyph.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetGlyphPlacements)(
+ __in_ecount(textLength) WCHAR const* textString,
+ __in_ecount(textLength) UINT16 const* clusterMap,
+ __in_ecount(textLength) DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
+ UINT32 textLength,
+ __in_ecount(glyphCount) UINT16 const* glyphIndices,
+ __in_ecount(glyphCount) DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps,
+ UINT32 glyphCount,
+ IDWriteFontFace * fontFace,
+ FLOAT fontEmSize,
+ BOOL isSideways,
+ BOOL isRightToLeft,
+ __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
+ __in_z_opt WCHAR const* localeName,
+ __in_ecount_opt(featureRanges) DWRITE_TYPOGRAPHIC_FEATURES const** features,
+ __in_ecount_opt(featureRanges) UINT32 const* featureRangeLengths,
+ UINT32 featureRanges,
+ __out_ecount(glyphCount) FLOAT* glyphAdvances,
+ __out_ecount(glyphCount) DWRITE_GLYPH_OFFSET* glyphOffsets
+ ) PURE;
+
+ /// <summary>
+ /// Place glyphs output from the GetGlyphs method according to the font
+ /// and the writing system's rendering rules.
+ /// </summary>
+ /// <param name="textString">The original string the glyphs came from.</param>
+ /// <param name="clusterMap">The mapping from character ranges to glyph
+ /// ranges. Returned by GetGlyphs.</param>
+ /// <param name="textProps">Per-character properties. Returned by
+ /// GetGlyphs.</param>
+ /// <param name="textLength">The length of textString.</param>
+ /// <param name="glyphIndices">Glyph indices. See GetGlyphs</param>
+ /// <param name="glyphProps">Per-glyph properties. See GetGlyphs</param>
+ /// <param name="glyphCount">The number of glyphs.</param>
+ /// <param name="fontFace">The font face the glyphs came from.</param>
+ /// <param name="fontEmSize">Logical font size in DIP's.</param>
+ /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if the DPI of the rendering surface is 96 this
+ /// value is 1.0f. If the DPI is 120, this value is 120.0f/96.</param>
+ /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
+ /// scaling specified by the font size and pixelsPerDip.</param>
+ /// <param name="useGdiNatural">
+ /// When set to FALSE, the metrics are the same as the metrics of GDI aliased text.
+ /// When set to TRUE, the metrics are the same as the metrics of text measured by GDI using a font
+ /// created with CLEARTYPE_NATURAL_QUALITY.
+ /// </param>
+ /// <param name="isSideways">Set to true if the text is intended to be
+ /// drawn vertically.</param>
+ /// <param name="isRightToLeft">Set to TRUE for right-to-left text.</param>
+ /// <param name="scriptAnalysis">Script analysis result from AnalyzeScript.</param>
+ /// <param name="localeName">The locale to use when selecting glyphs.
+ /// e.g. the same character may map to different glyphs for ja-jp vs zh-chs.
+ /// If this is NULL then the default mapping based on the script is used.</param>
+ /// <param name="features">An array of pointers to the sets of typographic
+ /// features to use in each feature range.</param>
+ /// <param name="featureRangeLengths">The length of each feature range, in characters.
+ /// The sum of all lengths should be equal to textLength.</param>
+ /// <param name="featureRanges">The number of feature ranges.</param>
+ /// <param name="glyphAdvances">The advance width of each glyph.</param>
+ /// <param name="glyphOffsets">The offset of the origin of each glyph.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetGdiCompatibleGlyphPlacements)(
+ __in_ecount(textLength) WCHAR const* textString,
+ __in_ecount(textLength) UINT16 const* clusterMap,
+ __in_ecount(textLength) DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
+ UINT32 textLength,
+ __in_ecount(glyphCount) UINT16 const* glyphIndices,
+ __in_ecount(glyphCount) DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps,
+ UINT32 glyphCount,
+ IDWriteFontFace * fontFace,
+ FLOAT fontEmSize,
+ FLOAT pixelsPerDip,
+ __in_opt DWRITE_MATRIX const* transform,
+ BOOL useGdiNatural,
+ BOOL isSideways,
+ BOOL isRightToLeft,
+ __in DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
+ __in_z_opt WCHAR const* localeName,
+ __in_ecount_opt(featureRanges) DWRITE_TYPOGRAPHIC_FEATURES const** features,
+ __in_ecount_opt(featureRanges) UINT32 const* featureRangeLengths,
+ UINT32 featureRanges,
+ __out_ecount(glyphCount) FLOAT* glyphAdvances,
+ __out_ecount(glyphCount) DWRITE_GLYPH_OFFSET* glyphOffsets
+ ) PURE;
+};
+
+/// <summary>
+/// The DWRITE_GLYPH_RUN structure contains the information needed by renderers
+/// to draw glyph runs. All coordinates are in device independent pixels (DIPs).
+/// </summary>
+struct DWRITE_GLYPH_RUN
+{
+ /// <summary>
+ /// The physical font face to draw with.
+ /// </summary>
+ __notnull IDWriteFontFace* fontFace;
+
+ /// <summary>
+ /// Logical size of the font in DIPs, not points (equals 1/96 inch).
+ /// </summary>
+ FLOAT fontEmSize;
+
+ /// <summary>
+ /// The number of glyphs.
+ /// </summary>
+ UINT32 glyphCount;
+
+ /// <summary>
+ /// The indices to render.
+ /// </summary>
+ __field_ecount(glyphCount) UINT16 const* glyphIndices;
+
+ /// <summary>
+ /// Glyph advance widths.
+ /// </summary>
+ __field_ecount_opt(glyphCount) FLOAT const* glyphAdvances;
+
+ /// <summary>
+ /// Glyph offsets.
+ /// </summary>
+ __field_ecount_opt(glyphCount) DWRITE_GLYPH_OFFSET const* glyphOffsets;
+
+ /// <summary>
+ /// If true, specifies that glyphs are rotated 90 degrees to the left and
+ /// vertical metrics are used. Vertical writing is achieved by specifying
+ /// isSideways = true and rotating the entire run 90 degrees to the right
+ /// via a rotate transform.
+ /// </summary>
+ BOOL isSideways;
+
+ /// <summary>
+ /// The implicit resolved bidi level of the run. Odd levels indicate
+ /// right-to-left languages like Hebrew and Arabic, while even levels
+ /// indicate left-to-right languages like English and Japanese (when
+ /// written horizontally). For right-to-left languages, the text origin
+ /// is on the right, and text should be drawn to the left.
+ /// </summary>
+ UINT32 bidiLevel;
+};
+
+/// <summary>
+/// The DWRITE_GLYPH_RUN_DESCRIPTION structure contains additional properties
+/// related to those in DWRITE_GLYPH_RUN.
+/// </summary>
+struct DWRITE_GLYPH_RUN_DESCRIPTION
+{
+ /// <summary>
+ /// The locale name associated with this run.
+ /// </summary>
+ __nullterminated WCHAR const* localeName;
+
+ /// <summary>
+ /// The text associated with the glyphs.
+ /// </summary>
+ __field_ecount(stringLength) WCHAR const* string;
+
+ /// <summary>
+ /// The number of characters (UTF16 code-units).
+ /// Note that this may be different than the number of glyphs.
+ /// </summary>
+ UINT32 stringLength;
+
+ /// <summary>
+ /// An array of indices to the glyph indices array, of the first glyphs of
+ /// all the glyph clusters of the glyphs to render.
+ /// </summary>
+ __field_ecount(stringLength) UINT16 const* clusterMap;
+
+ /// <summary>
+ /// Corresponding text position in the original string
+ /// this glyph run came from.
+ /// </summary>
+ UINT32 textPosition;
+};
+
+/// <summary>
+/// The DWRITE_UNDERLINE structure contains about the size and placement of
+/// underlines. All coordinates are in device independent pixels (DIPs).
+/// </summary>
+struct DWRITE_UNDERLINE
+{
+ /// <summary>
+ /// Width of the underline, measured parallel to the baseline.
+ /// </summary>
+ FLOAT width;
+
+ /// <summary>
+ /// Thickness of the underline, measured perpendicular to the
+ /// baseline.
+ /// </summary>
+ FLOAT thickness;
+
+ /// <summary>
+ /// Offset of the underline from the baseline.
+ /// A positive offset represents a position below the baseline and
+ /// a negative offset is above.
+ /// </summary>
+ FLOAT offset;
+
+ /// <summary>
+ /// Height of the tallest run where the underline applies.
+ /// </summary>
+ FLOAT runHeight;
+
+ /// <summary>
+ /// Reading direction of the text associated with the underline. This
+ /// value is used to interpret whether the width value runs horizontally
+ /// or vertically.
+ /// </summary>
+ DWRITE_READING_DIRECTION readingDirection;
+
+ /// <summary>
+ /// Flow direction of the text associated with the underline. This value
+ /// is used to interpret whether the thickness value advances top to
+ /// bottom, left to right, or right to left.
+ /// </summary>
+ DWRITE_FLOW_DIRECTION flowDirection;
+
+ /// <summary>
+ /// Locale of the text the underline is being drawn under. Can be
+ /// pertinent where the locale affects how the underline is drawn.
+ /// For example, in vertical text, the underline belongs on the
+ /// left for Chinese but on the right for Japanese.
+ /// This choice is completely left up to higher levels.
+ /// </summary>
+ __nullterminated WCHAR const* localeName;
+
+ /// <summary>
+ /// The measuring mode can be useful to the renderer to determine how
+ /// underlines are rendered, e.g. rounding the thickness to a whole pixel
+ /// in GDI-compatible modes.
+ /// </summary>
+ DWRITE_MEASURING_MODE measuringMode;
+};
+
+/// <summary>
+/// The DWRITE_STRIKETHROUGH structure contains about the size and placement of
+/// strickthroughs. All coordinates are in device independent pixels (DIPs).
+/// </summary>
+struct DWRITE_STRIKETHROUGH
+{
+ /// <summary>
+ /// Width of the strikethrough, measured parallel to the baseline.
+ /// </summary>
+ FLOAT width;
+
+ /// <summary>
+ /// Thickness of the strikethrough, measured perpendicular to the
+ /// baseline.
+ /// </summary>
+ FLOAT thickness;
+
+ /// <summary>
+ /// Offset of the stikethrough from the baseline.
+ /// A positive offset represents a position below the baseline and
+ /// a negative offset is above.
+ /// </summary>
+ FLOAT offset;
+
+ /// <summary>
+ /// Reading direction of the text associated with the strikethrough. This
+ /// value is used to interpret whether the width value runs horizontally
+ /// or vertically.
+ /// </summary>
+ DWRITE_READING_DIRECTION readingDirection;
+
+ /// <summary>
+ /// Flow direction of the text associated with the strikethrough. This
+ /// value is used to interpret whether the thickness value advances top to
+ /// bottom, left to right, or right to left.
+ /// </summary>
+ DWRITE_FLOW_DIRECTION flowDirection;
+
+ /// <summary>
+ /// Locale of the range. Can be pertinent where the locale affects the style.
+ /// </summary>
+ __nullterminated WCHAR const* localeName;
+
+ /// <summary>
+ /// The measuring mode can be useful to the renderer to determine how
+ /// underlines are rendered, e.g. rounding the thickness to a whole pixel
+ /// in GDI-compatible modes.
+ /// </summary>
+ DWRITE_MEASURING_MODE measuringMode;
+};
+
+/// <summary>
+/// The DWRITE_LINE_METRICS structure contains information about a formatted
+/// line of text.
+/// </summary>
+struct DWRITE_LINE_METRICS
+{
+ /// <summary>
+ /// The number of total text positions in the line.
+ /// This includes any trailing whitespace and newline characters.
+ /// </summary>
+ UINT32 length;
+
+ /// <summary>
+ /// The number of whitespace positions at the end of the line. Newline
+ /// sequences are considered whitespace.
+ /// </summary>
+ UINT32 trailingWhitespaceLength;
+
+ /// <summary>
+ /// The number of characters in the newline sequence at the end of the line.
+ /// If the count is zero, then the line was either wrapped or it is the
+ /// end of the text.
+ /// </summary>
+ UINT32 newlineLength;
+
+ /// <summary>
+ /// Height of the line as measured from top to bottom.
+ /// </summary>
+ FLOAT height;
+
+ /// <summary>
+ /// Distance from the top of the line to its baseline.
+ /// </summary>
+ FLOAT baseline;
+
+ /// <summary>
+ /// The line is trimmed.
+ /// </summary>
+ BOOL isTrimmed;
+};
+
+
+/// <summary>
+/// The DWRITE_CLUSTER_METRICS structure contains information about a glyph cluster.
+/// </summary>
+struct DWRITE_CLUSTER_METRICS
+{
+ /// <summary>
+ /// The total advance width of all glyphs in the cluster.
+ /// </summary>
+ FLOAT width;
+
+ /// <summary>
+ /// The number of text positions in the cluster.
+ /// </summary>
+ UINT16 length;
+
+ /// <summary>
+ /// Indicate whether line can be broken right after the cluster.
+ /// </summary>
+ UINT16 canWrapLineAfter : 1;
+
+ /// <summary>
+ /// Indicate whether the cluster corresponds to whitespace character.
+ /// </summary>
+ UINT16 isWhitespace : 1;
+
+ /// <summary>
+ /// Indicate whether the cluster corresponds to a newline character.
+ /// </summary>
+ UINT16 isNewline : 1;
+
+ /// <summary>
+ /// Indicate whether the cluster corresponds to soft hyphen character.
+ /// </summary>
+ UINT16 isSoftHyphen : 1;
+
+ /// <summary>
+ /// Indicate whether the cluster is read from right to left.
+ /// </summary>
+ UINT16 isRightToLeft : 1;
+
+ UINT16 padding : 11;
+};
+
+
+/// <summary>
+/// Overall metrics associated with text after layout.
+/// All coordinates are in device independent pixels (DIPs).
+/// </summary>
+struct DWRITE_TEXT_METRICS
+{
+ /// <summary>
+ /// Left-most point of formatted text relative to layout box
+ /// (excluding any glyph overhang).
+ /// </summary>
+ FLOAT left;
+
+ /// <summary>
+ /// Top-most point of formatted text relative to layout box
+ /// (excluding any glyph overhang).
+ /// </summary>
+ FLOAT top;
+
+ /// <summary>
+ /// The width of the formatted text ignoring trailing whitespace
+ /// at the end of each line.
+ /// </summary>
+ FLOAT width;
+
+ /// <summary>
+ /// The width of the formatted text taking into account the
+ /// trailing whitespace at the end of each line.
+ /// </summary>
+ FLOAT widthIncludingTrailingWhitespace;
+
+ /// <summary>
+ /// The height of the formatted text. The height of an empty string
+ /// is determined by the size of the default font's line height.
+ /// </summary>
+ FLOAT height;
+
+ /// <summary>
+ /// Initial width given to the layout. Depending on whether the text
+ /// was wrapped or not, it can be either larger or smaller than the
+ /// text content width.
+ /// </summary>
+ FLOAT layoutWidth;
+
+ /// <summary>
+ /// Initial height given to the layout. Depending on the length of the
+ /// text, it may be larger or smaller than the text content height.
+ /// </summary>
+ FLOAT layoutHeight;
+
+ /// <summary>
+ /// The maximum reordering count of any line of text, used
+ /// to calculate the most number of hit-testing boxes needed.
+ /// If the layout has no bidirectional text or no text at all,
+ /// the minimum level is 1.
+ /// </summary>
+ UINT32 maxBidiReorderingDepth;
+
+ /// <summary>
+ /// Total number of lines.
+ /// </summary>
+ UINT32 lineCount;
+};
+
+
+/// <summary>
+/// Properties describing the geometric measurement of an
+/// application-defined inline object.
+/// </summary>
+struct DWRITE_INLINE_OBJECT_METRICS
+{
+ /// <summary>
+ /// Width of the inline object.
+ /// </summary>
+ FLOAT width;
+
+ /// <summary>
+ /// Height of the inline object as measured from top to bottom.
+ /// </summary>
+ FLOAT height;
+
+ /// <summary>
+ /// Distance from the top of the object to the baseline where it is lined up with the adjacent text.
+ /// If the baseline is at the bottom, baseline simply equals height.
+ /// </summary>
+ FLOAT baseline;
+
+ /// <summary>
+ /// Flag indicating whether the object is to be placed upright or alongside the text baseline
+ /// for vertical text.
+ /// </summary>
+ BOOL supportsSideways;
+};
+
+
+/// <summary>
+/// The DWRITE_OVERHANG_METRICS structure holds how much any visible pixels
+/// (in DIPs) overshoot each side of the layout or inline objects.
+/// </summary>
+/// <remarks>
+/// Positive overhangs indicate that the visible area extends outside the layout
+/// box or inline object, while negative values mean there is whitespace inside.
+/// The returned values are unaffected by rendering transforms or pixel snapping.
+/// Additionally, they may not exactly match final target's pixel bounds after
+/// applying grid fitting and hinting.
+/// </remarks>
+struct DWRITE_OVERHANG_METRICS
+{
+ /// <summary>
+ /// The distance from the left-most visible DIP to its left alignment edge.
+ /// </summary>
+ FLOAT left;
+
+ /// <summary>
+ /// The distance from the top-most visible DIP to its top alignment edge.
+ /// </summary>
+ FLOAT top;
+
+ /// <summary>
+ /// The distance from the right-most visible DIP to its right alignment edge.
+ /// </summary>
+ FLOAT right;
+
+ /// <summary>
+ /// The distance from the bottom-most visible DIP to its bottom alignment edge.
+ /// </summary>
+ FLOAT bottom;
+};
+
+
+/// <summary>
+/// Geometry enclosing of text positions.
+/// </summary>
+struct DWRITE_HIT_TEST_METRICS
+{
+ /// <summary>
+ /// First text position within the geometry.
+ /// </summary>
+ UINT32 textPosition;
+
+ /// <summary>
+ /// Number of text positions within the geometry.
+ /// </summary>
+ UINT32 length;
+
+ /// <summary>
+ /// Left position of the top-left coordinate of the geometry.
+ /// </summary>
+ FLOAT left;
+
+ /// <summary>
+ /// Top position of the top-left coordinate of the geometry.
+ /// </summary>
+ FLOAT top;
+
+ /// <summary>
+ /// Geometry's width.
+ /// </summary>
+ FLOAT width;
+
+ /// <summary>
+ /// Geometry's height.
+ /// </summary>
+ FLOAT height;
+
+ /// <summary>
+ /// Bidi level of text positions enclosed within the geometry.
+ /// </summary>
+ UINT32 bidiLevel;
+
+ /// <summary>
+ /// Geometry encloses text?
+ /// </summary>
+ BOOL isText;
+
+ /// <summary>
+ /// Range is trimmed.
+ /// </summary>
+ BOOL isTrimmed;
+};
+
+
+interface IDWriteTextRenderer;
+
+
+/// <summary>
+/// The IDWriteInlineObject interface wraps an application defined inline graphic,
+/// allowing DWrite to query metrics as if it was a glyph inline with the text.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("8339FDE3-106F-47ab-8373-1C6295EB10B3") IDWriteInlineObject : public IUnknown
+{
+ /// <summary>
+ /// The application implemented rendering callback (IDWriteTextRenderer::DrawInlineObject)
+ /// can use this to draw the inline object without needing to cast or query the object
+ /// type. The text layout does not call this method directly.
+ /// </summary>
+ /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
+ /// <param name="renderer">The renderer passed to IDWriteTextLayout::Draw as the object's containing parent.</param>
+ /// <param name="originX">X-coordinate at the top-left corner of the inline object.</param>
+ /// <param name="originY">Y-coordinate at the top-left corner of the inline object.</param>
+ /// <param name="isSideways">The object should be drawn on its side.</param>
+ /// <param name="isRightToLeft">The object is in an right-to-left context and should be drawn flipped.</param>
+ /// <param name="clientDrawingEffect">The drawing effect set in IDWriteTextLayout::SetDrawingEffect.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(Draw)(
+ __maybenull void* clientDrawingContext,
+ IDWriteTextRenderer* renderer,
+ FLOAT originX,
+ FLOAT originY,
+ BOOL isSideways,
+ BOOL isRightToLeft,
+ __maybenull IUnknown* clientDrawingEffect
+ ) PURE;
+
+ /// <summary>
+ /// TextLayout calls this callback function to get the measurement of the inline object.
+ /// </summary>
+ /// <param name="metrics">Returned metrics</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetMetrics)(
+ __out DWRITE_INLINE_OBJECT_METRICS* metrics
+ ) PURE;
+
+ /// <summary>
+ /// TextLayout calls this callback function to get the visible extents (in DIPs) of the inline object.
+ /// In the case of a simple bitmap, with no padding and no overhang, all the overhangs will
+ /// simply be zeroes.
+ /// </summary>
+ /// <param name="overhangs">Overshoot of visible extents (in DIPs) outside the object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// The overhangs should be returned relative to the reported size of the object
+ /// (DWRITE_INLINE_OBJECT_METRICS::width/height), and should not be baseline
+ /// adjusted. If you have an image that is actually 100x100 DIPs, but you want it
+ /// slightly inset (perhaps it has a glow) by 20 DIPs on each side, you would
+ /// return a width/height of 60x60 and four overhangs of 20 DIPs.
+ /// </remarks>
+ STDMETHOD(GetOverhangMetrics)(
+ __out DWRITE_OVERHANG_METRICS* overhangs
+ ) PURE;
+
+ /// <summary>
+ /// Layout uses this to determine the line breaking behavior of the inline object
+ /// amidst the text.
+ /// </summary>
+ /// <param name="breakConditionBefore">Line-breaking condition between the object and the content immediately preceding it.</param>
+ /// <param name="breakConditionAfter" >Line-breaking condition between the object and the content immediately following it.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetBreakConditions)(
+ __out DWRITE_BREAK_CONDITION* breakConditionBefore,
+ __out DWRITE_BREAK_CONDITION* breakConditionAfter
+ ) PURE;
+};
+
+/// <summary>
+/// The IDWritePixelSnapping interface defines the pixel snapping properties of a text renderer.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("eaf3a2da-ecf4-4d24-b644-b34f6842024b") IDWritePixelSnapping : public IUnknown
+{
+ /// <summary>
+ /// Determines whether pixel snapping is disabled. The recommended default is FALSE,
+ /// unless doing animation that requires subpixel vertical placement.
+ /// </summary>
+ /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
+ /// <param name="isDisabled">Receives TRUE if pixel snapping is disabled or FALSE if it not.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(IsPixelSnappingDisabled)(
+ __maybenull void* clientDrawingContext,
+ __out BOOL* isDisabled
+ ) PURE;
+
+ /// <summary>
+ /// Gets the current transform that maps abstract coordinates to DIPs,
+ /// which may disable pixel snapping upon any rotation or shear.
+ /// </summary>
+ /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
+ /// <param name="transform">Receives the transform.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetCurrentTransform)(
+ __maybenull void* clientDrawingContext,
+ __out DWRITE_MATRIX* transform
+ ) PURE;
+
+ /// <summary>
+ /// Gets the number of physical pixels per DIP. A DIP (device-independent pixel) is 1/96 inch,
+ /// so the pixelsPerDip value is the number of logical pixels per inch divided by 96 (yielding
+ /// a value of 1 for 96 DPI and 1.25 for 120).
+ /// </summary>
+ /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
+ /// <param name="pixelsPerDip">Receives the number of physical pixels per DIP.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetPixelsPerDip)(
+ __maybenull void* clientDrawingContext,
+ __out FLOAT* pixelsPerDip
+ ) PURE;
+};
+
+/// <summary>
+/// The IDWriteTextLayout interface represents a set of application-defined
+/// callbacks that perform rendering of text, inline objects, and decorations
+/// such as underlines.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("ef8a8135-5cc6-45fe-8825-c5a0724eb819") IDWriteTextRenderer : public IDWritePixelSnapping
+{
+ /// <summary>
+ /// IDWriteTextLayout::Draw calls this function to instruct the client to
+ /// render a run of glyphs.
+ /// </summary>
+ /// <param name="clientDrawingContext">The context passed to
+ /// IDWriteTextLayout::Draw.</param>
+ /// <param name="baselineOriginX">X-coordinate of the baseline.</param>
+ /// <param name="baselineOriginY">Y-coordinate of the baseline.</param>
+ /// <param name="measuringMode">Specifies measuring method for glyphs in the run.
+ /// Renderer implementations may choose different rendering modes for given measuring methods,
+ /// but best results are seen when the rendering mode matches the corresponding measuring mode:
+ /// DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL for DWRITE_MEASURING_MODE_NATURAL
+ /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC for DWRITE_MEASURING_MODE_GDI_CLASSIC
+ /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL for DWRITE_MEASURING_MODE_GDI_NATURAL
+ /// </param>
+ /// <param name="glyphRun">The glyph run to draw.</param>
+ /// <param name="glyphRunDescription">Properties of the characters
+ /// associated with this run.</param>
+ /// <param name="clientDrawingEffect">The drawing effect set in
+ /// IDWriteTextLayout::SetDrawingEffect.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(DrawGlyphRun)(
+ __maybenull void* clientDrawingContext,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_MEASURING_MODE measuringMode,
+ __in DWRITE_GLYPH_RUN const* glyphRun,
+ __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
+ __maybenull IUnknown* clientDrawingEffect
+ ) PURE;
+
+ /// <summary>
+ /// IDWriteTextLayout::Draw calls this function to instruct the client to draw
+ /// an underline.
+ /// </summary>
+ /// <param name="clientDrawingContext">The context passed to
+ /// IDWriteTextLayout::Draw.</param>
+ /// <param name="baselineOriginX">X-coordinate of the baseline.</param>
+ /// <param name="baselineOriginY">Y-coordinate of the baseline.</param>
+ /// <param name="underline">Underline logical information.</param>
+ /// <param name="clientDrawingEffect">The drawing effect set in
+ /// IDWriteTextLayout::SetDrawingEffect.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// A single underline can be broken into multiple calls, depending on
+ /// how the formatting changes attributes. If font sizes/styles change
+ /// within an underline, the thickness and offset will be averaged
+ /// weighted according to characters.
+ /// To get the correct top coordinate of the underline rect, add underline::offset
+ /// to the baseline's Y. Otherwise the underline will be immediately under the text.
+ /// The x coordinate will always be passed as the left side, regardless
+ /// of text directionality. This simplifies drawing and reduces the
+ /// problem of round-off that could potentially cause gaps or a double
+ /// stamped alpha blend. To avoid alpha overlap, round the end points
+ /// to the nearest device pixel.
+ /// </remarks>
+ STDMETHOD(DrawUnderline)(
+ __maybenull void* clientDrawingContext,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ __in DWRITE_UNDERLINE const* underline,
+ __maybenull IUnknown* clientDrawingEffect
+ ) PURE;
+
+ /// <summary>
+ /// IDWriteTextLayout::Draw calls this function to instruct the client to draw
+ /// a strikethrough.
+ /// </summary>
+ /// <param name="clientDrawingContext">The context passed to
+ /// IDWriteTextLayout::Draw.</param>
+ /// <param name="baselineOriginX">X-coordinate of the baseline.</param>
+ /// <param name="baselineOriginY">Y-coordinate of the baseline.</param>
+ /// <param name="strikethrough">Strikethrough logical information.</param>
+ /// <param name="clientDrawingEffect">The drawing effect set in
+ /// IDWriteTextLayout::SetDrawingEffect.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// A single strikethrough can be broken into multiple calls, depending on
+ /// how the formatting changes attributes. Strikethrough is not averaged
+ /// across font sizes/styles changes.
+ /// To get the correct top coordinate of the strikethrough rect,
+ /// add strikethrough::offset to the baseline's Y.
+ /// Like underlines, the x coordinate will always be passed as the left side,
+ /// regardless of text directionality.
+ /// </remarks>
+ STDMETHOD(DrawStrikethrough)(
+ __maybenull void* clientDrawingContext,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ __in DWRITE_STRIKETHROUGH const* strikethrough,
+ __maybenull IUnknown* clientDrawingEffect
+ ) PURE;
+
+ /// <summary>
+ /// IDWriteTextLayout::Draw calls this application callback when it needs to
+ /// draw an inline object.
+ /// </summary>
+ /// <param name="clientDrawingContext">The context passed to IDWriteTextLayout::Draw.</param>
+ /// <param name="originX">X-coordinate at the top-left corner of the inline object.</param>
+ /// <param name="originY">Y-coordinate at the top-left corner of the inline object.</param>
+ /// <param name="inlineObject">The object set using IDWriteTextLayout::SetInlineObject.</param>
+ /// <param name="isSideways">The object should be drawn on its side.</param>
+ /// <param name="isRightToLeft">The object is in an right-to-left context and should be drawn flipped.</param>
+ /// <param name="clientDrawingEffect">The drawing effect set in
+ /// IDWriteTextLayout::SetDrawingEffect.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// The right-to-left flag is a hint for those cases where it would look
+ /// strange for the image to be shown normally (like an arrow pointing to
+ /// right to indicate a submenu).
+ /// </remarks>
+ STDMETHOD(DrawInlineObject)(
+ __maybenull void* clientDrawingContext,
+ FLOAT originX,
+ FLOAT originY,
+ IDWriteInlineObject* inlineObject,
+ BOOL isSideways,
+ BOOL isRightToLeft,
+ __maybenull IUnknown* clientDrawingEffect
+ ) PURE;
+};
+
+/// <summary>
+/// The IDWriteTextLayout interface represents a block of text after it has
+/// been fully analyzed and formatted.
+///
+/// All coordinates are in device independent pixels (DIPs).
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("53737037-6d14-410b-9bfe-0b182bb70961") IDWriteTextLayout : public IDWriteTextFormat
+{
+ /// <summary>
+ /// Set layout maximum width
+ /// </summary>
+ /// <param name="maxWidth">Layout maximum width</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetMaxWidth)(
+ FLOAT maxWidth
+ ) PURE;
+
+ /// <summary>
+ /// Set layout maximum height
+ /// </summary>
+ /// <param name="maxHeight">Layout maximum height</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetMaxHeight)(
+ FLOAT maxHeight
+ ) PURE;
+
+ /// <summary>
+ /// Set the font collection.
+ /// </summary>
+ /// <param name="fontCollection">The font collection to set</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetFontCollection)(
+ IDWriteFontCollection* fontCollection,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set null-terminated font family name.
+ /// </summary>
+ /// <param name="fontFamilyName">Font family name</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetFontFamilyName)(
+ __in_z WCHAR const* fontFamilyName,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set font weight.
+ /// </summary>
+ /// <param name="fontWeight">Font weight</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetFontWeight)(
+ DWRITE_FONT_WEIGHT fontWeight,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set font style.
+ /// </summary>
+ /// <param name="fontStyle">Font style</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetFontStyle)(
+ DWRITE_FONT_STYLE fontStyle,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set font stretch.
+ /// </summary>
+ /// <param name="fontStretch">font stretch</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetFontStretch)(
+ DWRITE_FONT_STRETCH fontStretch,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set font em height.
+ /// </summary>
+ /// <param name="fontSize">Font em height</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetFontSize)(
+ FLOAT fontSize,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set underline.
+ /// </summary>
+ /// <param name="hasUnderline">The Boolean flag indicates whether underline takes place</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetUnderline)(
+ BOOL hasUnderline,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set strikethrough.
+ /// </summary>
+ /// <param name="hasStrikethrough">The Boolean flag indicates whether strikethrough takes place</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetStrikethrough)(
+ BOOL hasStrikethrough,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set application-defined drawing effect.
+ /// </summary>
+ /// <param name="drawingEffect">Pointer to an application-defined drawing effect.</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// This drawing effect is associated with the specified range and will be passed back
+ /// to the application via the callback when the range is drawn at drawing time.
+ /// </remarks>
+ STDMETHOD(SetDrawingEffect)(
+ IUnknown* drawingEffect,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set inline object.
+ /// </summary>
+ /// <param name="inlineObject">Pointer to an application-implemented inline object.</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// This inline object applies to the specified range and will be passed back
+ /// to the application via the DrawInlineObject callback when the range is drawn.
+ /// Any text in that range will be suppressed.
+ /// </remarks>
+ STDMETHOD(SetInlineObject)(
+ IDWriteInlineObject* inlineObject,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set font typography features.
+ /// </summary>
+ /// <param name="typography">Pointer to font typography setting.</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetTypography)(
+ IDWriteTypography* typography,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Set locale name.
+ /// </summary>
+ /// <param name="localeName">Locale name</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetLocaleName)(
+ __in_z WCHAR const* localeName,
+ DWRITE_TEXT_RANGE textRange
+ ) PURE;
+
+ /// <summary>
+ /// Get layout maximum width
+ /// </summary>
+ STDMETHOD_(FLOAT, GetMaxWidth)() PURE;
+
+ /// <summary>
+ /// Get layout maximum height
+ /// </summary>
+ STDMETHOD_(FLOAT, GetMaxHeight)() PURE;
+
+ /// <summary>
+ /// Get the font collection where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="fontCollection">The current font collection</param>
+ /// <param name="textRange">Text range to which this change applies.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontCollection)(
+ UINT32 currentPosition,
+ __out IDWriteFontCollection** fontCollection,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the length of the font family name where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="nameLength">Size of the character array in character count not including the terminated NULL character.</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontFamilyNameLength)(
+ UINT32 currentPosition,
+ __out UINT32* nameLength,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Copy the font family name where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="fontFamilyName">Character array that receives the current font family name</param>
+ /// <param name="nameSize">Size of the character array in character count including the terminated NULL character.</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontFamilyName)(
+ UINT32 currentPosition,
+ __out_ecount_z(nameSize) WCHAR* fontFamilyName,
+ UINT32 nameSize,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the font weight where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="fontWeight">The current font weight</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontWeight)(
+ UINT32 currentPosition,
+ __out DWRITE_FONT_WEIGHT* fontWeight,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the font style where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="fontStyle">The current font style</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontStyle)(
+ UINT32 currentPosition,
+ __out DWRITE_FONT_STYLE* fontStyle,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the font stretch where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="fontStretch">The current font stretch</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontStretch)(
+ UINT32 currentPosition,
+ __out DWRITE_FONT_STRETCH* fontStretch,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the font em height where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="fontSize">The current font em height</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetFontSize)(
+ UINT32 currentPosition,
+ __out FLOAT* fontSize,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the underline presence where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="hasUnderline">The Boolean flag indicates whether text is underlined.</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetUnderline)(
+ UINT32 currentPosition,
+ __out BOOL* hasUnderline,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the strikethrough presence where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="hasStrikethrough">The Boolean flag indicates whether text has strikethrough.</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetStrikethrough)(
+ UINT32 currentPosition,
+ __out BOOL* hasStrikethrough,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the application-defined drawing effect where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="drawingEffect">The current application-defined drawing effect.</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetDrawingEffect)(
+ UINT32 currentPosition,
+ __out IUnknown** drawingEffect,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the inline object at the given position.
+ /// </summary>
+ /// <param name="currentPosition">The given text position.</param>
+ /// <param name="inlineObject">The inline object.</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetInlineObject)(
+ UINT32 currentPosition,
+ __out IDWriteInlineObject** inlineObject,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the typography setting where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="typography">The current typography setting.</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetTypography)(
+ UINT32 currentPosition,
+ __out IDWriteTypography** typography,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the length of the locale name where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="nameLength">Size of the character array in character count not including the terminated NULL character.</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetLocaleNameLength)(
+ UINT32 currentPosition,
+ __out UINT32* nameLength,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Get the locale name where the current position is at.
+ /// </summary>
+ /// <param name="currentPosition">The current text position.</param>
+ /// <param name="localeName">Character array that receives the current locale name</param>
+ /// <param name="nameSize">Size of the character array in character count including the terminated NULL character.</param>
+ /// <param name="textRange">The position range of the current format.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetLocaleName)(
+ UINT32 currentPosition,
+ __out_ecount_z(nameSize) WCHAR* localeName,
+ UINT32 nameSize,
+ __out_opt DWRITE_TEXT_RANGE* textRange = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Initiate drawing of the text.
+ /// </summary>
+ /// <param name="clientDrawingContext">An application defined value
+ /// included in rendering callbacks.</param>
+ /// <param name="renderer">The set of application-defined callbacks that do
+ /// the actual rendering.</param>
+ /// <param name="originX">X-coordinate of the layout's left side.</param>
+ /// <param name="originY">Y-coordinate of the layout's top side.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(Draw)(
+ __maybenull void* clientDrawingContext,
+ IDWriteTextRenderer* renderer,
+ FLOAT originX,
+ FLOAT originY
+ ) PURE;
+
+ /// <summary>
+ /// GetLineMetrics returns properties of each line.
+ /// </summary>
+ /// <param name="lineMetrics">The array to fill with line information.</param>
+ /// <param name="maxLineCount">The maximum size of the lineMetrics array.</param>
+ /// <param name="actualLineCount">The actual size of the lineMetrics
+ /// array that is needed.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// If maxLineCount is not large enough E_NOT_SUFFICIENT_BUFFER,
+ /// which is equivalent to HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
+ /// is returned and *actualLineCount is set to the number of lines
+ /// needed.
+ /// </remarks>
+ STDMETHOD(GetLineMetrics)(
+ __out_ecount_opt(maxLineCount) DWRITE_LINE_METRICS* lineMetrics,
+ UINT32 maxLineCount,
+ __out UINT32* actualLineCount
+ ) PURE;
+
+ /// <summary>
+ /// GetMetrics retrieves overall metrics for the formatted string.
+ /// </summary>
+ /// <param name="textMetrics">The returned metrics.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// Drawing effects like underline and strikethrough do not contribute
+ /// to the text size, which is essentially the sum of advance widths and
+ /// line heights. Additionally, visible swashes and other graphic
+ /// adornments may extend outside the returned width and height.
+ /// </remarks>
+ STDMETHOD(GetMetrics)(
+ __out DWRITE_TEXT_METRICS* textMetrics
+ ) PURE;
+
+ /// <summary>
+ /// GetOverhangMetrics returns the overhangs (in DIPs) of the layout and all
+ /// objects contained in it, including text glyphs and inline objects.
+ /// </summary>
+ /// <param name="overhangs">Overshoots of visible extents (in DIPs) outside the layout.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// Any underline and strikethrough do not contribute to the black box
+ /// determination, since these are actually drawn by the renderer, which
+ /// is allowed to draw them in any variety of styles.
+ /// </remarks>
+ STDMETHOD(GetOverhangMetrics)(
+ __out DWRITE_OVERHANG_METRICS* overhangs
+ ) PURE;
+
+ /// <summary>
+ /// Retrieve logical properties and measurement of each cluster.
+ /// </summary>
+ /// <param name="clusterMetrics">The array to fill with cluster information.</param>
+ /// <param name="maxClusterCount">The maximum size of the clusterMetrics array.</param>
+ /// <param name="actualClusterCount">The actual size of the clusterMetrics array that is needed.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// If maxClusterCount is not large enough E_NOT_SUFFICIENT_BUFFER,
+ /// which is equivalent to HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER),
+ /// is returned and *actualClusterCount is set to the number of clusters
+ /// needed.
+ /// </remarks>
+ STDMETHOD(GetClusterMetrics)(
+ __out_ecount_opt(maxClusterCount) DWRITE_CLUSTER_METRICS* clusterMetrics,
+ UINT32 maxClusterCount,
+ __out UINT32* actualClusterCount
+ ) PURE;
+
+ /// <summary>
+ /// Determines the minimum possible width the layout can be set to without
+ /// emergency breaking between the characters of whole words.
+ /// </summary>
+ /// <param name="minWidth">Minimum width.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(DetermineMinWidth)(
+ __out FLOAT* minWidth
+ ) PURE;
+
+ /// <summary>
+ /// Given a coordinate (in DIPs) relative to the top-left of the layout box,
+ /// this returns the corresponding hit-test metrics of the text string where
+ /// the hit-test has occurred. This is useful for mapping mouse clicks to caret
+ /// positions. When the given coordinate is outside the text string, the function
+ /// sets the output value *isInside to false but returns the nearest character
+ /// position.
+ /// </summary>
+ /// <param name="pointX">X coordinate to hit-test, relative to the top-left location of the layout box.</param>
+ /// <param name="pointY">Y coordinate to hit-test, relative to the top-left location of the layout box.</param>
+ /// <param name="isTrailingHit">Output flag indicating whether the hit-test location is at the leading or the trailing
+ /// side of the character. When the output *isInside value is set to false, this value is set according to the output
+ /// *position value to represent the edge closest to the hit-test location. </param>
+ /// <param name="isInside">Output flag indicating whether the hit-test location is inside the text string.
+ /// When false, the position nearest the text's edge is returned.</param>
+ /// <param name="hitTestMetrics">Output geometry fully enclosing the hit-test location. When the output *isInside value
+ /// is set to false, this structure represents the geometry enclosing the edge closest to the hit-test location.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(HitTestPoint)(
+ FLOAT pointX,
+ FLOAT pointY,
+ __out BOOL* isTrailingHit,
+ __out BOOL* isInside,
+ __out DWRITE_HIT_TEST_METRICS* hitTestMetrics
+ ) PURE;
+
+ /// <summary>
+ /// Given a text position and whether the caret is on the leading or trailing
+ /// edge of that position, this returns the corresponding coordinate (in DIPs)
+ /// relative to the top-left of the layout box. This is most useful for drawing
+ /// the caret's current position, but it could also be used to anchor an IME to the
+ /// typed text or attach a floating menu near the point of interest. It may also be
+ /// used to programmatically obtain the geometry of a particular text position
+ /// for UI automation.
+ /// </summary>
+ /// <param name="textPosition">Text position to get the coordinate of.</param>
+ /// <param name="isTrailingHit">Flag indicating whether the location is of the leading or the trailing side of the specified text position. </param>
+ /// <param name="pointX">Output caret X, relative to the top-left of the layout box.</param>
+ /// <param name="pointY">Output caret Y, relative to the top-left of the layout box.</param>
+ /// <param name="hitTestMetrics">Output geometry fully enclosing the specified text position.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// When drawing a caret at the returned X,Y, it should should be centered on X
+ /// and drawn from the Y coordinate down. The height will be the size of the
+ /// hit-tested text (which can vary in size within a line).
+ /// Reading direction also affects which side of the character the caret is drawn.
+ /// However, the returned X coordinate will be correct for either case.
+ /// You can get a text length back that is larger than a single character.
+ /// This happens for complex scripts when multiple characters form a single cluster,
+ /// when diacritics join their base character, or when you test a surrogate pair.
+ /// </remarks>
+ STDMETHOD(HitTestTextPosition)(
+ UINT32 textPosition,
+ BOOL isTrailingHit,
+ __out FLOAT* pointX,
+ __out FLOAT* pointY,
+ __out DWRITE_HIT_TEST_METRICS* hitTestMetrics
+ ) PURE;
+
+ /// <summary>
+ /// The application calls this function to get a set of hit-test metrics
+ /// corresponding to a range of text positions. The main usage for this
+ /// is to draw highlighted selection of the text string.
+ ///
+ /// The function returns E_NOT_SUFFICIENT_BUFFER, which is equivalent to
+ /// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER), when the buffer size of
+ /// hitTestMetrics is too small to hold all the regions calculated by the
+ /// function. In such situation, the function sets the output value
+ /// *actualHitTestMetricsCount to the number of geometries calculated.
+ /// The application is responsible to allocate a new buffer of greater
+ /// size and call the function again.
+ ///
+ /// A good value to use as an initial value for maxHitTestMetricsCount may
+ /// be calculated from the following equation:
+ /// maxHitTestMetricsCount = lineCount * maxBidiReorderingDepth
+ ///
+ /// where lineCount is obtained from the value of the output argument
+ /// *actualLineCount from the function IDWriteTextLayout::GetLineMetrics,
+ /// and the maxBidiReorderingDepth value from the DWRITE_TEXT_METRICS
+ /// structure of the output argument *textMetrics from the function
+ /// IDWriteFactory::CreateTextLayout.
+ /// </summary>
+ /// <param name="textPosition">First text position of the specified range.</param>
+ /// <param name="textLength">Number of positions of the specified range.</param>
+ /// <param name="originX">Offset of the X origin (left of the layout box) which is added to each of the hit-test metrics returned.</param>
+ /// <param name="originY">Offset of the Y origin (top of the layout box) which is added to each of the hit-test metrics returned.</param>
+ /// <param name="hitTestMetrics">Pointer to a buffer of the output geometry fully enclosing the specified position range.</param>
+ /// <param name="maxHitTestMetricsCount">Maximum number of distinct metrics it could hold in its buffer memory.</param>
+ /// <param name="actualHitTestMetricsCount">Actual number of metrics returned or needed.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// There are no gaps in the returned metrics. While there could be visual gaps,
+ /// depending on bidi ordering, each range is contiguous and reports all the text,
+ /// including any hidden characters and trimmed text.
+ /// The height of each returned range will be the same within each line, regardless
+ /// of how the font sizes vary.
+ /// </remarks>
+ STDMETHOD(HitTestTextRange)(
+ UINT32 textPosition,
+ UINT32 textLength,
+ FLOAT originX,
+ FLOAT originY,
+ __out_ecount_opt(maxHitTestMetricsCount) DWRITE_HIT_TEST_METRICS* hitTestMetrics,
+ UINT32 maxHitTestMetricsCount,
+ __out UINT32* actualHitTestMetricsCount
+ ) PURE;
+};
+
+/// <summary>
+/// Encapsulates a 32-bit device independent bitmap and device context, which can be used for rendering glyphs.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("5e5a32a3-8dff-4773-9ff6-0696eab77267") IDWriteBitmapRenderTarget : public IUnknown
+{
+ /// <summary>
+ /// Draws a run of glyphs to the bitmap.
+ /// </summary>
+ /// <param name="baselineOriginX">Horizontal position of the baseline origin, in DIPs, relative to the upper-left corner of the DIB.</param>
+ /// <param name="baselineOriginY">Vertical position of the baseline origin, in DIPs, relative to the upper-left corner of the DIB.</param>
+ /// <param name="measuringMode">Specifies measuring method for glyphs in the run.
+ /// Renderer implementations may choose different rendering modes for different measuring methods, for example
+ /// DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL for DWRITE_MEASURING_MODE_NATURAL,
+ /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC for DWRITE_MEASURING_MODE_GDI_CLASSIC, and
+ /// DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL for DWRITE_MEASURING_MODE_GDI_NATURAL.
+ /// </param>
+ /// <param name="glyphRun">Structure containing the properties of the glyph run.</param>
+ /// <param name="renderingParams">Object that controls rendering behavior.</param>
+ /// <param name="textColor">Specifies the foreground color of the text.</param>
+ /// <param name="blackBoxRect">Optional rectangle that receives the bounding box (in pixels not DIPs) of all the pixels affected by
+ /// drawing the glyph run. The black box rectangle may extend beyond the dimensions of the bitmap.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(DrawGlyphRun)(
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_MEASURING_MODE measuringMode,
+ __in DWRITE_GLYPH_RUN const* glyphRun,
+ IDWriteRenderingParams* renderingParams,
+ COLORREF textColor,
+ __out_opt RECT* blackBoxRect = NULL
+ ) PURE;
+
+ /// <summary>
+ /// Gets a handle to the memory device context.
+ /// </summary>
+ /// <returns>
+ /// Returns the device context handle.
+ /// </returns>
+ /// <remarks>
+ /// An application can use the device context to draw using GDI functions. An application can obtain the bitmap handle
+ /// (HBITMAP) by calling GetCurrentObject. An application that wants information about the underlying bitmap, including
+ /// a pointer to the pixel data, can call GetObject to fill in a DIBSECTION structure. The bitmap is always a 32-bit
+ /// top-down DIB.
+ /// </remarks>
+ STDMETHOD_(HDC, GetMemoryDC)() PURE;
+
+ /// <summary>
+ /// Gets the number of bitmap pixels per DIP. A DIP (device-independent pixel) is 1/96 inch so this value is the number
+ /// if pixels per inch divided by 96.
+ /// </summary>
+ /// <returns>
+ /// Returns the number of bitmap pixels per DIP.
+ /// </returns>
+ STDMETHOD_(FLOAT, GetPixelsPerDip)() PURE;
+
+ /// <summary>
+ /// Sets the number of bitmap pixels per DIP. A DIP (device-independent pixel) is 1/96 inch so this value is the number
+ /// if pixels per inch divided by 96.
+ /// </summary>
+ /// <param name="pixelsPerDip">Specifies the number of pixels per DIP.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetPixelsPerDip)(
+ FLOAT pixelsPerDip
+ ) PURE;
+
+ /// <summary>
+ /// Gets the transform that maps abstract coordinate to DIPs. By default this is the identity
+ /// transform. Note that this is unrelated to the world transform of the underlying device
+ /// context.
+ /// </summary>
+ /// <param name="transform">Receives the transform.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetCurrentTransform)(
+ __out DWRITE_MATRIX* transform
+ ) PURE;
+
+ /// <summary>
+ /// Sets the transform that maps abstract coordinate to DIPs. This does not affect the world
+ /// transform of the underlying device context.
+ /// </summary>
+ /// <param name="transform">Specifies the new transform. This parameter can be NULL, in which
+ /// case the identity transform is implied.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(SetCurrentTransform)(
+ __in_opt DWRITE_MATRIX const* transform
+ ) PURE;
+
+ /// <summary>
+ /// Gets the dimensions of the bitmap.
+ /// </summary>
+ /// <param name="size">Receives the size of the bitmap in pixels.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetSize)(
+ __out SIZE* size
+ ) PURE;
+
+ /// <summary>
+ /// Resizes the bitmap.
+ /// </summary>
+ /// <param name="width">New bitmap width, in pixels.</param>
+ /// <param name="height">New bitmap height, in pixels.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(Resize)(
+ UINT32 width,
+ UINT32 height
+ ) PURE;
+};
+
+/// <summary>
+/// The GDI interop interface provides interoperability with GDI.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("1edd9491-9853-4299-898f-6432983b6f3a") IDWriteGdiInterop : public IUnknown
+{
+ /// <summary>
+ /// Creates a font object that matches the properties specified by the LOGFONT structure.
+ /// </summary>
+ /// <param name="logFont">Structure containing a GDI-compatible font description.</param>
+ /// <param name="font">Receives a newly created font object if successful, or NULL in case of error.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateFontFromLOGFONT)(
+ __in LOGFONTW const* logFont,
+ __out IDWriteFont** font
+ ) PURE;
+
+ /// <summary>
+ /// Initializes a LOGFONT structure based on the GDI-compatible properties of the specified font.
+ /// </summary>
+ /// <param name="font">Specifies a font in the system font collection.</param>
+ /// <param name="logFont">Structure that receives a GDI-compatible font description.</param>
+ /// <param name="isSystemFont">Contains TRUE if the specified font object is part of the system font collection
+ /// or FALSE otherwise.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(ConvertFontToLOGFONT)(
+ IDWriteFont* font,
+ __out LOGFONTW* logFont,
+ __out BOOL* isSystemFont
+ ) PURE;
+
+ /// <summary>
+ /// Initializes a LOGFONT structure based on the GDI-compatible properties of the specified font.
+ /// </summary>
+ /// <param name="font">Specifies a font face.</param>
+ /// <param name="logFont">Structure that receives a GDI-compatible font description.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(ConvertFontFaceToLOGFONT)(
+ IDWriteFontFace* font,
+ __out LOGFONTW* logFont
+ ) PURE;
+
+ /// <summary>
+ /// Creates a font face object that corresponds to the currently selected HFONT.
+ /// </summary>
+ /// <param name="hdc">Handle to a device context into which a font has been selected. It is assumed that the client
+ /// has already performed font mapping and that the font selected into the DC is the actual font that would be used
+ /// for rendering glyphs.</param>
+ /// <param name="fontFace">Contains the newly created font face object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateFontFaceFromHdc)(
+ HDC hdc,
+ __out IDWriteFontFace** fontFace
+ ) PURE;
+
+ /// <summary>
+ /// Creates an object that encapsulates a bitmap and memory DC which can be used for rendering glyphs.
+ /// </summary>
+ /// <param name="hdc">Optional device context used to create a compatible memory DC.</param>
+ /// <param name="width">Width of the bitmap.</param>
+ /// <param name="height">Height of the bitmap.</param>
+ /// <param name="renderTarget">Receives a pointer to the newly created render target.</param>
+ STDMETHOD(CreateBitmapRenderTarget)(
+ __in_opt HDC hdc,
+ UINT32 width,
+ UINT32 height,
+ __out IDWriteBitmapRenderTarget** renderTarget
+ ) PURE;
+};
+
+/// <summary>
+/// The DWRITE_TEXTURE_TYPE enumeration identifies a type of alpha texture. An alpha texture is a bitmap of alpha values, each
+/// representing the darkness (i.e., opacity) of a pixel or subpixel.
+/// </summary>
+enum DWRITE_TEXTURE_TYPE
+{
+ /// <summary>
+ /// Specifies an alpha texture for aliased text rendering (i.e., bi-level, where each pixel is either fully opaque or fully transparent),
+ /// with one byte per pixel.
+ /// </summary>
+ DWRITE_TEXTURE_ALIASED_1x1,
+
+ /// <summary>
+ /// Specifies an alpha texture for ClearType text rendering, with three bytes per pixel in the horizontal dimension and
+ /// one byte per pixel in the vertical dimension.
+ /// </summary>
+ DWRITE_TEXTURE_CLEARTYPE_3x1
+};
+
+/// <summary>
+/// Maximum alpha value in a texture returned by IDWriteGlyphRunAnalysis::CreateAlphaTexture.
+/// </summary>
+#define DWRITE_ALPHA_MAX 255
+
+/// <summary>
+/// Interface that encapsulates information used to render a glyph run.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("7d97dbf7-e085-42d4-81e3-6a883bded118") IDWriteGlyphRunAnalysis : public IUnknown
+{
+ /// <summary>
+ /// Gets the bounding rectangle of the physical pixels affected by the glyph run.
+ /// </summary>
+ /// <param name="textureType">Specifies the type of texture requested. If a bi-level texture is requested, the
+ /// bounding rectangle includes only bi-level glyphs. Otherwise, the bounding rectangle includes only anti-aliased
+ /// glyphs.</param>
+ /// <param name="textureBounds">Receives the bounding rectangle, or an empty rectangle if there are no glyphs
+ /// if the specified type.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetAlphaTextureBounds)(
+ DWRITE_TEXTURE_TYPE textureType,
+ __out RECT* textureBounds
+ ) PURE;
+
+ /// <summary>
+ /// Creates an alpha texture of the specified type.
+ /// </summary>
+ /// <param name="textureType">Specifies the type of texture requested. If a bi-level texture is requested, the
+ /// texture contains only bi-level glyphs. Otherwise, the texture contains only anti-aliased glyphs.</param>
+ /// <param name="textureBounds">Specifies the bounding rectangle of the texture, which can be different than
+ /// the bounding rectangle returned by GetAlphaTextureBounds.</param>
+ /// <param name="alphaValues">Receives the array of alpha values.</param>
+ /// <param name="bufferSize">Size of the alphaValues array. The minimum size depends on the dimensions of the
+ /// rectangle and the type of texture requested.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateAlphaTexture)(
+ DWRITE_TEXTURE_TYPE textureType,
+ __in RECT const* textureBounds,
+ __out_bcount(bufferSize) BYTE* alphaValues,
+ UINT32 bufferSize
+ ) PURE;
+
+ /// <summary>
+ /// Gets properties required for ClearType blending.
+ /// </summary>
+ /// <param name="renderingParams">Rendering parameters object. In most cases, the values returned in the output
+ /// parameters are based on the properties of this object. The exception is if a GDI-compatible rendering mode
+ /// is specified.</param>
+ /// <param name="blendGamma">Receives the gamma value to use for gamma correction.</param>
+ /// <param name="blendEnhancedContrast">Receives the enhanced contrast value.</param>
+ /// <param name="blendClearTypeLevel">Receives the ClearType level.</param>
+ STDMETHOD(GetAlphaBlendParams)(
+ IDWriteRenderingParams* renderingParams,
+ __out FLOAT* blendGamma,
+ __out FLOAT* blendEnhancedContrast,
+ __out FLOAT* blendClearTypeLevel
+ ) PURE;
+};
+
+/// <summary>
+/// The root factory interface for all DWrite objects.
+/// </summary>
+interface DWRITE_DECLARE_INTERFACE("b859ee5a-d838-4b5b-a2e8-1adc7d93db48") IDWriteFactory : public IUnknown
+{
+ /// <summary>
+ /// Gets a font collection representing the set of installed fonts.
+ /// </summary>
+ /// <param name="fontCollection">Receives a pointer to the system font collection object, or NULL in case of failure.</param>
+ /// <param name="checkForUpdates">If this parameter is nonzero, the function performs an immediate check for changes to the set of
+ /// installed fonts. If this parameter is FALSE, the function will still detect changes if the font cache service is running, but
+ /// there may be some latency. For example, an application might specify TRUE if it has itself just installed a font and wants to
+ /// be sure the font collection contains that font.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetSystemFontCollection)(
+ __out IDWriteFontCollection** fontCollection,
+ BOOL checkForUpdates = FALSE
+ ) PURE;
+
+ /// <summary>
+ /// Creates a font collection using a custom font collection loader.
+ /// </summary>
+ /// <param name="collectionLoader">Application-defined font collection loader, which must have been previously
+ /// registered using RegisterFontCollectionLoader.</param>
+ /// <param name="collectionKey">Key used by the loader to identify a collection of font files.</param>
+ /// <param name="collectionKeySize">Size in bytes of the collection key.</param>
+ /// <param name="fontCollection">Receives a pointer to the system font collection object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateCustomFontCollection)(
+ IDWriteFontCollectionLoader* collectionLoader,
+ __in_bcount(collectionKeySize) void const* collectionKey,
+ UINT32 collectionKeySize,
+ __out IDWriteFontCollection** fontCollection
+ ) PURE;
+
+ /// <summary>
+ /// Registers a custom font collection loader with the factory object.
+ /// </summary>
+ /// <param name="fontCollectionLoader">Application-defined font collection loader.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(RegisterFontCollectionLoader)(
+ IDWriteFontCollectionLoader* fontCollectionLoader
+ ) PURE;
+
+ /// <summary>
+ /// Unregisters a custom font collection loader that was previously registered using RegisterFontCollectionLoader.
+ /// </summary>
+ /// <param name="fontCollectionLoader">Application-defined font collection loader.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(UnregisterFontCollectionLoader)(
+ IDWriteFontCollectionLoader* fontCollectionLoader
+ ) PURE;
+
+ /// <summary>
+ /// CreateFontFileReference creates a font file reference object from a local font file.
+ /// </summary>
+ /// <param name="filePath">Absolute file path. Subsequent operations on the constructed object may fail
+ /// if the user provided filePath doesn't correspond to a valid file on the disk.</param>
+ /// <param name="lastWriteTime">Last modified time of the input file path. If the parameter is omitted,
+ /// the function will access the font file to obtain its last write time, so the clients are encouraged to specify this value
+ /// to avoid extra disk access. Subsequent operations on the constructed object may fail
+ /// if the user provided lastWriteTime doesn't match the file on the disk.</param>
+ /// <param name="fontFile">Contains newly created font file reference object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateFontFileReference)(
+ __in_z WCHAR const* filePath,
+ __in_opt FILETIME const* lastWriteTime,
+ __out IDWriteFontFile** fontFile
+ ) PURE;
+
+ /// <summary>
+ /// CreateCustomFontFileReference creates a reference to an application specific font file resource.
+ /// This function enables an application or a document to use a font without having to install it on the system.
+ /// The fontFileReferenceKey has to be unique only in the scope of the fontFileLoader used in this call.
+ /// </summary>
+ /// <param name="fontFileReferenceKey">Font file reference key that uniquely identifies the font file resource
+ /// during the lifetime of fontFileLoader.</param>
+ /// <param name="fontFileReferenceKeySize">Size of font file reference key in bytes.</param>
+ /// <param name="fontFileLoader">Font file loader that will be used by the font system to load data from the file identified by
+ /// fontFileReferenceKey.</param>
+ /// <param name="fontFile">Contains the newly created font file object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// This function is provided for cases when an application or a document needs to use a font
+ /// without having to install it on the system. fontFileReferenceKey has to be unique only in the scope
+ /// of the fontFileLoader used in this call.
+ /// </remarks>
+ STDMETHOD(CreateCustomFontFileReference)(
+ __in_bcount(fontFileReferenceKeySize) void const* fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ IDWriteFontFileLoader* fontFileLoader,
+ __out IDWriteFontFile** fontFile
+ ) PURE;
+
+ /// <summary>
+ /// Creates a font face object.
+ /// </summary>
+ /// <param name="fontFaceType">The file format of the font face.</param>
+ /// <param name="numberOfFiles">The number of font files require to represent the font face.</param>
+ /// <param name="fontFiles">Font files representing the font face. Since IDWriteFontFace maintains its own references
+ /// to the input font file objects, it's OK to release them after this call.</param>
+ /// <param name="faceIndex">The zero based index of a font face in cases when the font files contain a collection of font faces.
+ /// If the font files contain a single face, this value should be zero.</param>
+ /// <param name="fontFaceSimulationFlags">Font face simulation flags for algorithmic emboldening and italicization.</param>
+ /// <param name="fontFace">Contains the newly created font face object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateFontFace)(
+ DWRITE_FONT_FACE_TYPE fontFaceType,
+ UINT32 numberOfFiles,
+ __in_ecount(numberOfFiles) IDWriteFontFile* const* fontFiles,
+ UINT32 faceIndex,
+ DWRITE_FONT_SIMULATIONS fontFaceSimulationFlags,
+ __out IDWriteFontFace** fontFace
+ ) PURE;
+
+ /// <summary>
+ /// Creates a rendering parameters object with default settings for the primary monitor.
+ /// </summary>
+ /// <param name="renderingParams">Holds the newly created rendering parameters object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateRenderingParams)(
+ __out IDWriteRenderingParams** renderingParams
+ ) PURE;
+
+ /// <summary>
+ /// Creates a rendering parameters object with default settings for the specified monitor.
+ /// </summary>
+ /// <param name="monitor">The monitor to read the default values from.</param>
+ /// <param name="renderingParams">Holds the newly created rendering parameters object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateMonitorRenderingParams)(
+ HMONITOR monitor,
+ __out IDWriteRenderingParams** renderingParams
+ ) PURE;
+
+ /// <summary>
+ /// Creates a rendering parameters object with the specified properties.
+ /// </summary>
+ /// <param name="gamma">The gamma value used for gamma correction, which must be greater than zero and cannot exceed 256.</param>
+ /// <param name="enhancedContrast">The amount of contrast enhancement, zero or greater.</param>
+ /// <param name="clearTypeLevel">The degree of ClearType level, from 0.0f (no ClearType) to 1.0f (full ClearType).</param>
+ /// <param name="pixelGeometry">The geometry of a device pixel.</param>
+ /// <param name="renderingMode">Method of rendering glyphs. In most cases, this should be DWRITE_RENDERING_MODE_DEFAULT to automatically use an appropriate mode.</param>
+ /// <param name="renderingParams">Holds the newly created rendering parameters object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateCustomRenderingParams)(
+ FLOAT gamma,
+ FLOAT enhancedContrast,
+ FLOAT clearTypeLevel,
+ DWRITE_PIXEL_GEOMETRY pixelGeometry,
+ DWRITE_RENDERING_MODE renderingMode,
+ __out IDWriteRenderingParams** renderingParams
+ ) PURE;
+
+ /// <summary>
+ /// Registers a font file loader with DirectWrite.
+ /// </summary>
+ /// <param name="fontFileLoader">Pointer to the implementation of the IDWriteFontFileLoader for a particular file resource type.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ /// <remarks>
+ /// This function registers a font file loader with DirectWrite.
+ /// Font file loader interface handles loading font file resources of a particular type from a key.
+ /// The font file loader interface is recommended to be implemented by a singleton object.
+ /// A given instance can only be registered once.
+ /// Succeeding attempts will return an error that it has already been registered.
+ /// IMPORTANT: font file loader implementations must not register themselves with DirectWrite
+ /// inside their constructors and must not unregister themselves in their destructors, because
+ /// registration and unregistraton operations increment and decrement the object reference count respectively.
+ /// Instead, registration and unregistration of font file loaders with DirectWrite should be performed
+ /// outside of the font file loader implementation as a separate step.
+ /// </remarks>
+ STDMETHOD(RegisterFontFileLoader)(
+ IDWriteFontFileLoader* fontFileLoader
+ ) PURE;
+
+ /// <summary>
+ /// Unregisters a font file loader that was previously registered with the DirectWrite font system using RegisterFontFileLoader.
+ /// </summary>
+ /// <param name="fontFileLoader">Pointer to the file loader that was previously registered with the DirectWrite font system using RegisterFontFileLoader.</param>
+ /// <returns>
+ /// This function will succeed if the user loader is requested to be removed.
+ /// It will fail if the pointer to the file loader identifies a standard DirectWrite loader,
+ /// or a loader that is never registered or has already been unregistered.
+ /// </returns>
+ /// <remarks>
+ /// This function unregisters font file loader callbacks with the DirectWrite font system.
+ /// The font file loader interface is recommended to be implemented by a singleton object.
+ /// IMPORTANT: font file loader implementations must not register themselves with DirectWrite
+ /// inside their constructors and must not unregister themselves in their destructors, because
+ /// registration and unregistraton operations increment and decrement the object reference count respectively.
+ /// Instead, registration and unregistration of font file loaders with DirectWrite should be performed
+ /// outside of the font file loader implementation as a separate step.
+ /// </remarks>
+ STDMETHOD(UnregisterFontFileLoader)(
+ IDWriteFontFileLoader* fontFileLoader
+ ) PURE;
+
+ /// <summary>
+ /// Create a text format object used for text layout.
+ /// </summary>
+ /// <param name="fontFamilyName">Name of the font family</param>
+ /// <param name="fontCollection">Font collection. NULL indicates the system font collection.</param>
+ /// <param name="fontWeight">Font weight</param>
+ /// <param name="fontStyle">Font style</param>
+ /// <param name="fontStretch">Font stretch</param>
+ /// <param name="fontSize">Logical size of the font in DIP units. A DIP ("device-independent pixel") equals 1/96 inch.</param>
+ /// <param name="localeName">Locale name</param>
+ /// <param name="textFormat">Contains newly created text format object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateTextFormat)(
+ __in_z WCHAR const* fontFamilyName,
+ __maybenull IDWriteFontCollection* fontCollection,
+ DWRITE_FONT_WEIGHT fontWeight,
+ DWRITE_FONT_STYLE fontStyle,
+ DWRITE_FONT_STRETCH fontStretch,
+ FLOAT fontSize,
+ __in_z WCHAR const* localeName,
+ __out IDWriteTextFormat** textFormat
+ ) PURE;
+
+ /// <summary>
+ /// Create a typography object used in conjunction with text format for text layout.
+ /// </summary>
+ /// <param name="typography">Contains newly created typography object, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateTypography)(
+ __out IDWriteTypography** typography
+ ) PURE;
+
+ /// <summary>
+ /// Create an object used for interoperability with GDI.
+ /// </summary>
+ /// <param name="gdiInterop">Receives the GDI interop object if successful, or NULL in case of failure.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(GetGdiInterop)(
+ __out IDWriteGdiInterop** gdiInterop
+ ) PURE;
+
+ /// <summary>
+ /// CreateTextLayout takes a string, format, and associated constraints
+ /// and produces and object representing the fully analyzed
+ /// and formatted result.
+ /// </summary>
+ /// <param name="string">The string to layout.</param>
+ /// <param name="stringLength">The length of the string.</param>
+ /// <param name="textFormat">The format to apply to the string.</param>
+ /// <param name="maxWidth">Width of the layout box.</param>
+ /// <param name="maxHeight">Height of the layout box.</param>
+ /// <param name="textLayout">The resultant object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateTextLayout)(
+ __in_ecount(stringLength) WCHAR const* string,
+ UINT32 stringLength,
+ IDWriteTextFormat* textFormat,
+ FLOAT maxWidth,
+ FLOAT maxHeight,
+ __out IDWriteTextLayout** textLayout
+ ) PURE;
+
+ /// <summary>
+ /// CreateGdiCompatibleTextLayout takes a string, format, and associated constraints
+ /// and produces and object representing the result formatted for a particular display resolution
+ /// and measuring method. The resulting text layout should only be used for the intended resolution,
+ /// and for cases where text scalability is desired, CreateTextLayout should be used instead.
+ /// </summary>
+ /// <param name="string">The string to layout.</param>
+ /// <param name="stringLength">The length of the string.</param>
+ /// <param name="textFormat">The format to apply to the string.</param>
+ /// <param name="layoutWidth">Width of the layout box.</param>
+ /// <param name="layoutHeight">Height of the layout box.</param>
+ /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if rendering onto a 96 DPI device then pixelsPerDip
+ /// is 1. If rendering onto a 120 DPI device then pixelsPerDip is 120/96.</param>
+ /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
+ /// scaling specified the font size and pixelsPerDip.</param>
+ /// <param name="useGdiNatural">
+ /// When set to FALSE, instructs the text layout to use the same metrics as GDI aliased text.
+ /// When set to TRUE, instructs the text layout to use the same metrics as text measured by GDI using a font
+ /// created with CLEARTYPE_NATURAL_QUALITY.
+ /// </param>
+ /// <param name="textLayout">The resultant object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateGdiCompatibleTextLayout)(
+ __in_ecount(stringLength) WCHAR const* string,
+ UINT32 stringLength,
+ IDWriteTextFormat* textFormat,
+ FLOAT layoutWidth,
+ FLOAT layoutHeight,
+ FLOAT pixelsPerDip,
+ __in_opt DWRITE_MATRIX const* transform,
+ BOOL useGdiNatural,
+ __out IDWriteTextLayout** textLayout
+ ) PURE;
+
+ /// <summary>
+ /// The application may call this function to create an inline object for trimming, using an ellipsis as the omission sign.
+ /// The ellipsis will be created using the current settings of the format, including base font, style, and any effects.
+ /// Alternate omission signs can be created by the application by implementing IDWriteInlineObject.
+ /// </summary>
+ /// <param name="textFormat">Text format used as a template for the omission sign.</param>
+ /// <param name="trimmingSign">Created omission sign.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateEllipsisTrimmingSign)(
+ IDWriteTextFormat* textFormat,
+ __out IDWriteInlineObject** trimmingSign
+ ) PURE;
+
+ /// <summary>
+ /// Return an interface to perform text analysis with.
+ /// </summary>
+ /// <param name="textAnalyzer">The resultant object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateTextAnalyzer)(
+ __out IDWriteTextAnalyzer** textAnalyzer
+ ) PURE;
+
+ /// <summary>
+ /// Creates a number substitution object using a locale name,
+ /// substitution method, and whether to ignore user overrides (uses NLS
+ /// defaults for the given culture instead).
+ /// </summary>
+ /// <param name="substitutionMethod">Method of number substitution to use.</param>
+ /// <param name="localeName">Which locale to obtain the digits from.</param>
+ /// <param name="ignoreUserOverride">Ignore the user's settings and use the locale defaults</param>
+ /// <param name="numberSubstitution">Receives a pointer to the newly created object.</param>
+ STDMETHOD(CreateNumberSubstitution)(
+ __in DWRITE_NUMBER_SUBSTITUTION_METHOD substitutionMethod,
+ __in_z WCHAR const* localeName,
+ __in BOOL ignoreUserOverride,
+ __out IDWriteNumberSubstitution** numberSubstitution
+ ) PURE;
+
+ /// <summary>
+ /// Creates a glyph run analysis object, which encapsulates information
+ /// used to render a glyph run.
+ /// </summary>
+ /// <param name="glyphRun">Structure specifying the properties of the glyph run.</param>
+ /// <param name="pixelsPerDip">Number of physical pixels per DIP. For example, if rendering onto a 96 DPI bitmap then pixelsPerDip
+ /// is 1. If rendering onto a 120 DPI bitmap then pixelsPerDip is 120/96.</param>
+ /// <param name="transform">Optional transform applied to the glyphs and their positions. This transform is applied after the
+ /// scaling specified the emSize and pixelsPerDip.</param>
+ /// <param name="renderingMode">Specifies the rendering mode, which must be one of the raster rendering modes (i.e., not default
+ /// and not outline).</param>
+ /// <param name="measuringMode">Specifies the method to measure glyphs.</param>
+ /// <param name="baselineOriginX">Horizontal position of the baseline origin, in DIPs.</param>
+ /// <param name="baselineOriginY">Vertical position of the baseline origin, in DIPs.</param>
+ /// <param name="glyphRunAnalysis">Receives a pointer to the newly created object.</param>
+ /// <returns>
+ /// Standard HRESULT error code.
+ /// </returns>
+ STDMETHOD(CreateGlyphRunAnalysis)(
+ __in DWRITE_GLYPH_RUN const* glyphRun,
+ FLOAT pixelsPerDip,
+ __in_opt DWRITE_MATRIX const* transform,
+ DWRITE_RENDERING_MODE renderingMode,
+ DWRITE_MEASURING_MODE measuringMode,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ __out IDWriteGlyphRunAnalysis** glyphRunAnalysis
+ ) PURE;
+
+}; // interface IDWriteFactory
+
+/// <summary>
+/// Creates a DirectWrite factory object that is used for subsequent creation of individual DirectWrite objects.
+/// </summary>
+/// <param name="factoryType">Identifies whether the factory object will be shared or isolated.</param>
+/// <param name="iid">Identifies the DirectWrite factory interface, such as __uuidof(IDWriteFactory).</param>
+/// <param name="factory">Receives the DirectWrite factory object.</param>
+/// <returns>
+/// Standard HRESULT error code.
+/// </returns>
+/// <remarks>
+/// Obtains DirectWrite factory object that is used for subsequent creation of individual DirectWrite classes.
+/// DirectWrite factory contains internal state such as font loader registration and cached font data.
+/// In most cases it is recommended to use the shared factory object, because it allows multiple components
+/// that use DirectWrite to share internal DirectWrite state and reduce memory usage.
+/// However, there are cases when it is desirable to reduce the impact of a component,
+/// such as a plug-in from an untrusted source, on the rest of the process by sandboxing and isolating it
+/// from the rest of the process components. In such cases, it is recommended to use an isolated factory for the sandboxed
+/// component.
+/// </remarks>
+EXTERN_C HRESULT DWRITE_EXPORT DWriteCreateFactory(
+ __in DWRITE_FACTORY_TYPE factoryType,
+ __in REFIID iid,
+ __out IUnknown **factory
+ );
+
+// Macros used to define DirectWrite error codes.
+#define FACILITY_DWRITE 0x898
+#define DWRITE_ERR_BASE 0x5000
+#define MAKE_DWRITE_HR(severity, code) MAKE_HRESULT(severity, FACILITY_DWRITE, (DWRITE_ERR_BASE + code))
+#define MAKE_DWRITE_HR_ERR(code) MAKE_DWRITE_HR(SEVERITY_ERROR, code)
+
+/// <summary>
+/// Indicates an error in an input file such as a font file.
+/// </summary>
+#define DWRITE_E_FILEFORMAT MAKE_DWRITE_HR_ERR(0x000)
+
+/// <summary>
+/// Indicates an error originating in DirectWrite code, which is not expected to occur but is safe to recover from.
+/// </summary>
+#define DWRITE_E_UNEXPECTED MAKE_DWRITE_HR_ERR(0x001)
+
+/// <summary>
+/// Indicates the specified font does not exist.
+/// </summary>
+#define DWRITE_E_NOFONT MAKE_DWRITE_HR_ERR(0x002)
+
+/// <summary>
+/// A font file could not be opened because the file, directory, network location, drive, or other storage
+/// location does not exist or is unavailable.
+/// </summary>
+#define DWRITE_E_FILENOTFOUND MAKE_DWRITE_HR_ERR(0x003)
+
+/// <summary>
+/// A font file exists but could not be opened due to access denied, sharing violation, or similar error.
+/// </summary>
+#define DWRITE_E_FILEACCESS MAKE_DWRITE_HR_ERR(0x004)
+
+/// <summary>
+/// A font collection is obsolete due to changes in the system.
+/// </summary>
+#define DWRITE_E_FONTCOLLECTIONOBSOLETE MAKE_DWRITE_HR_ERR(0x005)
+
+/// <summary>
+/// The given interface is already registered.
+/// </summary>
+#define DWRITE_E_ALREADYREGISTERED MAKE_DWRITE_HR_ERR(0x006)
+
+#endif /* DWRITE_H_INCLUDED */
diff --git a/core/src/fxge/Microsoft SDK/include/Dcommon.h b/core/src/fxge/Microsoft SDK/include/Dcommon.h
index a6c901aeac..4ecc5c174b 100644
--- a/core/src/fxge/Microsoft SDK/include/Dcommon.h
+++ b/core/src/fxge/Microsoft SDK/include/Dcommon.h
@@ -1,65 +1,65 @@
-//+--------------------------------------------------------------------------
-//
-// Copyright (c) Microsoft Corporation. All rights reserved.
-//
-// Abstract:
-// Public API definitions for DWrite and D2D
-//
-//----------------------------------------------------------------------------
-
-#ifndef DCOMMON_H_INCLUDED
-#define DCOMMON_H_INCLUDED
-
-//
-//These macros are defined in the Windows 7 SDK, however to enable development using the technical preview,
-//they are included here temporarily.
-//
-#ifndef DEFINE_ENUM_FLAG_OPERATORS
-#define DEFINE_ENUM_FLAG_OPERATORS(ENUMTYPE) \
-extern "C++" { \
-inline ENUMTYPE operator | (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) | ((int)b)); } \
-inline ENUMTYPE &operator |= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) |= ((int)b)); } \
-inline ENUMTYPE operator & (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) & ((int)b)); } \
-inline ENUMTYPE &operator &= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) &= ((int)b)); } \
-inline ENUMTYPE operator ~ (ENUMTYPE a) { return ENUMTYPE(~((int)a)); } \
-inline ENUMTYPE operator ^ (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) ^ ((int)b)); } \
-inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) ^= ((int)b)); } \
-}
-#endif
-
-#ifndef __field_ecount_opt
-#define __field_ecount_opt(x)
-#endif
-
-#ifndef __range
-#define __range(x,y)
-#endif
-
-#ifndef __field_ecount
-#define __field_ecount(x)
-#endif
-
-/// <summary>
-/// The measuring method used for text layout.
-/// </summary>
-typedef enum DWRITE_MEASURING_MODE
-{
- /// <summary>
- /// Text is measured using glyph ideal metrics whose values are independent to the current display resolution.
- /// </summary>
- DWRITE_MEASURING_MODE_NATURAL,
-
- /// <summary>
- /// Text is measured using glyph display compatible metrics whose values tuned for the current display resolution.
- /// </summary>
- DWRITE_MEASURING_MODE_GDI_CLASSIC,
-
- /// <summary>
- /// Text is measured using the same glyph display metrics as text measured by GDI using a font
- /// created with CLEARTYPE_NATURAL_QUALITY.
- /// </summary>
- DWRITE_MEASURING_MODE_GDI_NATURAL
-
-} DWRITE_MEASURING_MODE;
-
-#endif /* DCOMMON_H_INCLUDED */
+//+--------------------------------------------------------------------------
+//
+// Copyright (c) Microsoft Corporation. All rights reserved.
+//
+// Abstract:
+// Public API definitions for DWrite and D2D
+//
+//----------------------------------------------------------------------------
+
+#ifndef DCOMMON_H_INCLUDED
+#define DCOMMON_H_INCLUDED
+
+//
+//These macros are defined in the Windows 7 SDK, however to enable development using the technical preview,
+//they are included here temporarily.
+//
+#ifndef DEFINE_ENUM_FLAG_OPERATORS
+#define DEFINE_ENUM_FLAG_OPERATORS(ENUMTYPE) \
+extern "C++" { \
+inline ENUMTYPE operator | (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) | ((int)b)); } \
+inline ENUMTYPE &operator |= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) |= ((int)b)); } \
+inline ENUMTYPE operator & (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) & ((int)b)); } \
+inline ENUMTYPE &operator &= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) &= ((int)b)); } \
+inline ENUMTYPE operator ~ (ENUMTYPE a) { return ENUMTYPE(~((int)a)); } \
+inline ENUMTYPE operator ^ (ENUMTYPE a, ENUMTYPE b) { return ENUMTYPE(((int)a) ^ ((int)b)); } \
+inline ENUMTYPE &operator ^= (ENUMTYPE &a, ENUMTYPE b) { return (ENUMTYPE &)(((int &)a) ^= ((int)b)); } \
+}
+#endif
+
+#ifndef __field_ecount_opt
+#define __field_ecount_opt(x)
+#endif
+
+#ifndef __range
+#define __range(x,y)
+#endif
+
+#ifndef __field_ecount
+#define __field_ecount(x)
+#endif
+
+/// <summary>
+/// The measuring method used for text layout.
+/// </summary>
+typedef enum DWRITE_MEASURING_MODE
+{
+ /// <summary>
+ /// Text is measured using glyph ideal metrics whose values are independent to the current display resolution.
+ /// </summary>
+ DWRITE_MEASURING_MODE_NATURAL,
+
+ /// <summary>
+ /// Text is measured using glyph display compatible metrics whose values tuned for the current display resolution.
+ /// </summary>
+ DWRITE_MEASURING_MODE_GDI_CLASSIC,
+
+ /// <summary>
+ /// Text is measured using the same glyph display metrics as text measured by GDI using a font
+ /// created with CLEARTYPE_NATURAL_QUALITY.
+ /// </summary>
+ DWRITE_MEASURING_MODE_GDI_NATURAL
+
+} DWRITE_MEASURING_MODE;
+
+#endif /* DCOMMON_H_INCLUDED */
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlus.h b/core/src/fxge/Microsoft SDK/include/GdiPlus.h
index 82393e7050..75eb509469 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlus.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlus.h
@@ -1,156 +1,156 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* Gdiplus.h
-*
-* Abstract:
-*
-* GDI+ Native C++ public header file
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUS_H
-#define _GDIPLUS_H
-
-struct IDirectDrawSurface7;
-
-typedef signed short INT16;
-typedef unsigned short UINT16;
-
-#ifndef DCR_REMOVE_INTERNAL
-
-#ifndef DCR_USE_NEW_105760
- #define DCR_USE_NEW_105760
-#endif
-#ifndef DCR_USE_NEW_127084
- #define DCR_USE_NEW_127084
-#endif
-#ifndef DCR_USE_NEW_135429
- #define DCR_USE_NEW_135429
-#endif
-#ifndef DCR_USE_NEW_140782
- #define DCR_USE_NEW_140782
-#endif
-#ifndef DCR_USE_NEW_140855
- #define DCR_USE_NEW_140855
-#endif
-#ifndef DCR_USE_NEW_140857
- #define DCR_USE_NEW_140857
-#endif
-#ifndef DCR_USE_NEW_140861
- #define DCR_USE_NEW_140861
-#endif
-#ifndef DCR_USE_NEW_145135
- #define DCR_USE_NEW_145135
-#endif
-#ifndef DCR_USE_NEW_145138
- #define DCR_USE_NEW_145138
-#endif
-#ifndef DCR_USE_NEW_145139
- #define DCR_USE_NEW_145139
-#endif
-#ifndef DCR_USE_NEW_145804
- #define DCR_USE_NEW_145804
-#endif
-#ifndef DCR_USE_NEW_146933
- #define DCR_USE_NEW_146933
-#endif
-#ifndef DCR_USE_NEW_152154
- #define DCR_USE_NEW_152154
-#endif
-#ifndef DCR_USE_NEW_175866
- #define DCR_USE_NEW_175866
-#endif
-
-#ifndef DCR_USE_NEW_188922
- #define DCR_USE_NEW_188922
-#endif
-#ifndef DCR_USE_NEW_137252
- #define DCR_USE_NEW_137252
-#endif
-#ifndef DCR_USE_NEW_202903
- #define DCR_USE_NEW_202903
-#endif
-#ifndef DCR_USE_NEW_197819
- #define DCR_USE_NEW_197819
-#endif
-#ifndef DCR_USE_NEW_186091
- #define DCR_USE_NEW_186091
-#endif
-#ifndef DCR_USE_NEW_125467
- #define DCR_USE_NEW_125467
-#endif
-#ifndef DCR_USE_NEW_168772
- #define DCR_USE_NEW_168772
-#endif
-#ifndef DCR_USE_NEW_186764
- #define DCR_USE_NEW_186764
-#endif
-#ifndef DCR_USE_NEW_174340
- #define DCR_USE_NEW_174340
-#endif
-#ifndef DCR_USE_NEW_186151
- #define DCR_USE_NEW_186151
-#endif
-
-#ifndef DCR_USE_NEW_235072
- #define DCR_USE_NEW_235072
-#endif
-
-#endif // DCR_REMOVE_INTERNAL
-
-namespace Gdiplus
-{
- namespace DllExports
- {
- #include "GdiplusMem.h"
- };
-
- #include "GdiplusBase.h"
-
- // The following headers are used internally as well
- #include "GdiplusEnums.h"
- #include "GdiplusTypes.h"
- #include "GdiplusInit.h"
- #include "GdiplusPixelFormats.h"
- #include "GdiplusColor.h"
- #include "GdiplusMetaHeader.h"
- #include "GdiplusImaging.h"
- #include "GdiplusColorMatrix.h"
-
- // The rest of these are used only by the application
-
- #include "GdiplusGpStubs.h"
- #include "GdiplusHeaders.h"
-
- namespace DllExports
- {
- #include "GdiplusFlat.h"
- };
-
-
- #include "GdiplusImageAttributes.h"
- #include "GdiplusMatrix.h"
- #include "GdiplusBrush.h"
- #include "GdiplusPen.h"
- #include "GdiplusStringFormat.h"
- #include "GdiplusPath.h"
- #include "GdiplusLineCaps.h"
- #include "GdiplusMetafile.h"
- #include "GdiplusGraphics.h"
- #include "GdiplusCachedBitmap.h"
- #include "GdiplusRegion.h"
- #include "GdiplusFontCollection.h"
- #include "GdiplusFontFamily.h"
- #include "GdiplusFont.h"
- #include "GdiplusBitmap.h"
- #include "GdiplusImageCodec.h"
-
-}; // namespace Gdiplus
-
-
-
-#endif // !_GDIPLUS_HPP
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* Gdiplus.h
+*
+* Abstract:
+*
+* GDI+ Native C++ public header file
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUS_H
+#define _GDIPLUS_H
+
+struct IDirectDrawSurface7;
+
+typedef signed short INT16;
+typedef unsigned short UINT16;
+
+#ifndef DCR_REMOVE_INTERNAL
+
+#ifndef DCR_USE_NEW_105760
+ #define DCR_USE_NEW_105760
+#endif
+#ifndef DCR_USE_NEW_127084
+ #define DCR_USE_NEW_127084
+#endif
+#ifndef DCR_USE_NEW_135429
+ #define DCR_USE_NEW_135429
+#endif
+#ifndef DCR_USE_NEW_140782
+ #define DCR_USE_NEW_140782
+#endif
+#ifndef DCR_USE_NEW_140855
+ #define DCR_USE_NEW_140855
+#endif
+#ifndef DCR_USE_NEW_140857
+ #define DCR_USE_NEW_140857
+#endif
+#ifndef DCR_USE_NEW_140861
+ #define DCR_USE_NEW_140861
+#endif
+#ifndef DCR_USE_NEW_145135
+ #define DCR_USE_NEW_145135
+#endif
+#ifndef DCR_USE_NEW_145138
+ #define DCR_USE_NEW_145138
+#endif
+#ifndef DCR_USE_NEW_145139
+ #define DCR_USE_NEW_145139
+#endif
+#ifndef DCR_USE_NEW_145804
+ #define DCR_USE_NEW_145804
+#endif
+#ifndef DCR_USE_NEW_146933
+ #define DCR_USE_NEW_146933
+#endif
+#ifndef DCR_USE_NEW_152154
+ #define DCR_USE_NEW_152154
+#endif
+#ifndef DCR_USE_NEW_175866
+ #define DCR_USE_NEW_175866
+#endif
+
+#ifndef DCR_USE_NEW_188922
+ #define DCR_USE_NEW_188922
+#endif
+#ifndef DCR_USE_NEW_137252
+ #define DCR_USE_NEW_137252
+#endif
+#ifndef DCR_USE_NEW_202903
+ #define DCR_USE_NEW_202903
+#endif
+#ifndef DCR_USE_NEW_197819
+ #define DCR_USE_NEW_197819
+#endif
+#ifndef DCR_USE_NEW_186091
+ #define DCR_USE_NEW_186091
+#endif
+#ifndef DCR_USE_NEW_125467
+ #define DCR_USE_NEW_125467
+#endif
+#ifndef DCR_USE_NEW_168772
+ #define DCR_USE_NEW_168772
+#endif
+#ifndef DCR_USE_NEW_186764
+ #define DCR_USE_NEW_186764
+#endif
+#ifndef DCR_USE_NEW_174340
+ #define DCR_USE_NEW_174340
+#endif
+#ifndef DCR_USE_NEW_186151
+ #define DCR_USE_NEW_186151
+#endif
+
+#ifndef DCR_USE_NEW_235072
+ #define DCR_USE_NEW_235072
+#endif
+
+#endif // DCR_REMOVE_INTERNAL
+
+namespace Gdiplus
+{
+ namespace DllExports
+ {
+ #include "GdiplusMem.h"
+ };
+
+ #include "GdiplusBase.h"
+
+ // The following headers are used internally as well
+ #include "GdiplusEnums.h"
+ #include "GdiplusTypes.h"
+ #include "GdiplusInit.h"
+ #include "GdiplusPixelFormats.h"
+ #include "GdiplusColor.h"
+ #include "GdiplusMetaHeader.h"
+ #include "GdiplusImaging.h"
+ #include "GdiplusColorMatrix.h"
+
+ // The rest of these are used only by the application
+
+ #include "GdiplusGpStubs.h"
+ #include "GdiplusHeaders.h"
+
+ namespace DllExports
+ {
+ #include "GdiplusFlat.h"
+ };
+
+
+ #include "GdiplusImageAttributes.h"
+ #include "GdiplusMatrix.h"
+ #include "GdiplusBrush.h"
+ #include "GdiplusPen.h"
+ #include "GdiplusStringFormat.h"
+ #include "GdiplusPath.h"
+ #include "GdiplusLineCaps.h"
+ #include "GdiplusMetafile.h"
+ #include "GdiplusGraphics.h"
+ #include "GdiplusCachedBitmap.h"
+ #include "GdiplusRegion.h"
+ #include "GdiplusFontCollection.h"
+ #include "GdiplusFontFamily.h"
+ #include "GdiplusFont.h"
+ #include "GdiplusBitmap.h"
+ #include "GdiplusImageCodec.h"
+
+}; // namespace Gdiplus
+
+
+
+#endif // !_GDIPLUS_HPP
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusBase.h b/core/src/fxge/Microsoft SDK/include/GdiPlusBase.h
index 40a977d1b1..59f7cc2fee 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusBase.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusBase.h
@@ -1,40 +1,40 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusBase.h
-*
-* Abstract:
-*
-* Represents the base class for GDIPlus memory allocation.
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSBASE_H
-#define _GDIPLUSBASE_H
-
-class GdiplusBase
-{
-public:
- void (operator delete)(void* in_pVoid)
- {
- DllExports::GdipFree(in_pVoid);
- }
- void* (operator new)(size_t in_size)
- {
- return DllExports::GdipAlloc(in_size);
- }
- void (operator delete[])(void* in_pVoid)
- {
- DllExports::GdipFree(in_pVoid);
- }
- void* (operator new[])(size_t in_size)
- {
- return DllExports::GdipAlloc(in_size);
- }
-};
-
-#endif
-
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusBase.h
+*
+* Abstract:
+*
+* Represents the base class for GDIPlus memory allocation.
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSBASE_H
+#define _GDIPLUSBASE_H
+
+class GdiplusBase
+{
+public:
+ void (operator delete)(void* in_pVoid)
+ {
+ DllExports::GdipFree(in_pVoid);
+ }
+ void* (operator new)(size_t in_size)
+ {
+ return DllExports::GdipAlloc(in_size);
+ }
+ void (operator delete[])(void* in_pVoid)
+ {
+ DllExports::GdipFree(in_pVoid);
+ }
+ void* (operator new[])(size_t in_size)
+ {
+ return DllExports::GdipAlloc(in_size);
+ }
+};
+
+#endif
+
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusBitmap.h b/core/src/fxge/Microsoft SDK/include/GdiPlusBitmap.h
index fbe0061d41..16d66bdaeb 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusBitmap.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusBitmap.h
@@ -1,1004 +1,1004 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusBitmap.h
-*
-* Abstract:
-*
-* Bitmap related declarations
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSBITMAP_H
-#define _GDIPLUSBITMAP_H
-
-// NOTE:
-// Our current choice for the public API is to use constructors
-// instead of static load functions to create image objects.
-//
-// I've kept the static load functions here for now so that
-// existing test programs are not broken. But they should
-// eventually be taken out.
-
-#ifndef DCR_USE_NEW_140782
-
-inline
-Image::Image(
- IN const WCHAR* filename
- )
-{
- nativeImage = NULL;
- lastResult = DllExports::GdipLoadImageFromFile(filename, &nativeImage);
-}
-
-inline
-Image::Image(
- IN IStream* stream
- )
-{
- nativeImage = NULL;
- lastResult = DllExports::GdipLoadImageFromStream(stream, &nativeImage);
-}
-
-inline Image*
-Image::FromFile(
- IN const WCHAR* filename
- )
-{
- return new Image(filename);
-}
-
-inline Image*
-Image::FromStream(
- IN IStream* stream
- )
-{
- return new Image(stream);
-}
-
-#else
-
-inline
-Image::Image(
- IN const WCHAR* filename,
- IN BOOL useEmbeddedColorManagement
- )
-{
- nativeImage = NULL;
- if(useEmbeddedColorManagement)
- {
- lastResult = DllExports::GdipLoadImageFromFileICM(
- filename,
- &nativeImage
- );
- }
- else
- {
- lastResult = DllExports::GdipLoadImageFromFile(
- filename,
- &nativeImage
- );
- }
-}
-
-inline
-Image::Image(
- IN IStream* stream,
- IN BOOL useEmbeddedColorManagement
- )
-{
- nativeImage = NULL;
- if(useEmbeddedColorManagement)
- {
- lastResult = DllExports::GdipLoadImageFromStreamICM(
- stream,
- &nativeImage
- );
- }
- else
- {
- lastResult = DllExports::GdipLoadImageFromStream(
- stream,
- &nativeImage
- );
- }
-}
-
-inline Image*
-Image::FromFile(
- IN const WCHAR* filename,
- IN BOOL useEmbeddedColorManagement
- )
-{
- return new Image(
- filename,
- useEmbeddedColorManagement
- );
-}
-
-inline Image*
-Image::FromStream(
- IN IStream* stream,
- IN BOOL useEmbeddedColorManagement
- )
-{
- return new Image(
- stream,
- useEmbeddedColorManagement
- );
-}
-
-#endif
-
-inline
-Image::~Image()
-{
- DllExports::GdipDisposeImage(nativeImage);
-}
-
-inline Image*
-Image::Clone()
-{
- GpImage *cloneimage = NULL;
-
- SetStatus(DllExports::GdipCloneImage(nativeImage, &cloneimage));
-
- return new Image(cloneimage, lastResult);
-}
-
-// Encorder Parameter
-
-inline UINT
-Image::GetEncoderParameterListSize(
- IN const CLSID* clsidEncoder
- )
-{
- UINT size = 0;
-
- SetStatus(DllExports::GdipGetEncoderParameterListSize(nativeImage,
- clsidEncoder,
- &size));
- return size;
-}
-
-inline Status
-Image::GetEncoderParameterList(
- IN const CLSID* clsidEncoder,
- IN UINT size,
- OUT EncoderParameters* buffer
- )
-{
- return SetStatus(DllExports::GdipGetEncoderParameterList(nativeImage,
- clsidEncoder,
- size,
- buffer));
-}
-
-// Save images
-
-inline Status
-Image::Save(
- IN const WCHAR* filename,
- IN const CLSID* clsidEncoder,
- IN const EncoderParameters *encoderParams
- )
-{
- return SetStatus(DllExports::GdipSaveImageToFile(nativeImage,
- filename,
- clsidEncoder,
- encoderParams));
-}
-
-inline Status
-Image::Save(
- IN IStream* stream,
- IN const CLSID* clsidEncoder,
- IN const EncoderParameters *encoderParams
- )
-{
- return SetStatus(DllExports::GdipSaveImageToStream(nativeImage,
- stream,
- clsidEncoder,
- encoderParams));
-}
-
-inline Status
-Image::SaveAdd(
- IN const EncoderParameters *encoderParams
- )
-{
- return SetStatus(DllExports::GdipSaveAdd(nativeImage,
- encoderParams));
-}
-
-inline Status
-Image::SaveAdd(
- IN Image* newImage,
- IN const EncoderParameters *encoderParams
- )
-{
- if ( newImage == NULL )
- {
- return SetStatus(InvalidParameter);
- }
-
- return SetStatus(DllExports::GdipSaveAddImage(nativeImage,
- newImage->nativeImage,
- encoderParams));
-}
-
-// Get size and type information
-inline ImageType
-Image::GetType() const
-{
- ImageType type = ImageTypeUnknown;
-
- SetStatus(DllExports::GdipGetImageType(nativeImage, &type));
-
- return type;
-}
-
-inline Status
-Image::GetPhysicalDimension(
- OUT SizeF* size
- )
-{
- if (size == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- REAL width, height;
- Status status;
-
- status = SetStatus(DllExports::GdipGetImageDimension(nativeImage,
- &width, &height));
-
- size->Width = width;
- size->Height = height;
-
- return status;
-}
-
-inline Status
-Image::GetBounds(
- OUT RectF *srcRect,
- OUT Unit *srcUnit
- )
-{
- return SetStatus(DllExports::GdipGetImageBounds(nativeImage,
- srcRect, srcUnit));
-}
-
-inline UINT
-Image::GetWidth()
-{
- UINT width = 0;
-
- SetStatus(DllExports::GdipGetImageWidth(nativeImage, &width));
-
- return width;
-}
-
-inline UINT
-Image::GetHeight()
-{
- UINT height = 0;
-
- SetStatus(DllExports::GdipGetImageHeight(nativeImage, &height));
-
- return height;
-}
-
-inline REAL
-Image::GetHorizontalResolution()
-{
- REAL resolution = 0.0f;
-
- SetStatus(DllExports::GdipGetImageHorizontalResolution(nativeImage, &resolution));
-
- return resolution;
-}
-
-inline REAL
-Image::GetVerticalResolution()
-{
- REAL resolution = 0.0f;
-
- SetStatus(DllExports::GdipGetImageVerticalResolution(nativeImage, &resolution));
-
- return resolution;
-}
-
-inline UINT
-Image::GetFlags()
-{
- UINT flags = 0;
-
- SetStatus(DllExports::GdipGetImageFlags(nativeImage, &flags));
-
- return flags;
-}
-
-inline Status
-Image::GetRawFormat(OUT GUID *format)
-{
- return SetStatus(DllExports::GdipGetImageRawFormat(nativeImage, format));
-}
-
-inline PixelFormat
-Image::GetPixelFormat()
-{
- PixelFormat format;
-
- SetStatus(DllExports::GdipGetImagePixelFormat(nativeImage, &format));
-
- return format;
-}
-
-inline INT
-Image::GetPaletteSize()
-{
- INT size = 0;
-
- SetStatus(DllExports::GdipGetImagePaletteSize(nativeImage, &size));
-
- return size;
-}
-
-inline Status
-Image::GetPalette(
- OUT ColorPalette *palette,
- IN INT size
-)
-{
- return SetStatus(DllExports::GdipGetImagePalette(nativeImage, palette, size));
-}
-
-inline Status
-Image::SetPalette(
- IN const ColorPalette *palette
- )
-{
- return SetStatus(DllExports::GdipSetImagePalette(nativeImage, palette));
-}
-
-// Thumbnail support
-
-inline Image*
-Image::GetThumbnailImage(
- IN UINT thumbWidth,
- IN UINT thumbHeight,
- IN GetThumbnailImageAbort callback,
- IN VOID* callbackData
- )
-{
- GpImage *thumbimage = NULL;
-
- SetStatus(DllExports::GdipGetImageThumbnail(nativeImage,
- thumbWidth, thumbHeight,
- &thumbimage,
- callback, callbackData));
-
- Image *newImage = new Image(thumbimage, lastResult);
-
- if (newImage == NULL)
- {
- DllExports::GdipDisposeImage(thumbimage);
- }
-
- return newImage;
-}
-
-// Multi-frame support
-inline UINT
-Image::GetFrameDimensionsCount()
-{
- UINT count = 0;
-
- SetStatus(DllExports::GdipImageGetFrameDimensionsCount(nativeImage,
- &count));
-
- return count;
-}
-
-inline Status
-Image::GetFrameDimensionsList(
- OUT GUID* dimensionIDs,
- IN UINT count
- )
-{
- return SetStatus(DllExports::GdipImageGetFrameDimensionsList(nativeImage,
- dimensionIDs,
- count));
-}
-
-inline UINT
-Image::GetFrameCount(
- IN const GUID* dimensionID
- )
-{
- UINT count = 0;
-
- SetStatus(DllExports::GdipImageGetFrameCount(nativeImage,
- dimensionID,
- &count));
- return count;
-}
-
-inline Status
-Image::SelectActiveFrame(
- IN const GUID *dimensionID,
- IN UINT frameIndex
- )
-{
- return SetStatus(DllExports::GdipImageSelectActiveFrame(nativeImage,
- dimensionID,
- frameIndex));
-}
-
-inline Status
-Image::RotateFlip(
- IN RotateFlipType rotateFlipType
- )
-{
- return SetStatus(DllExports::GdipImageRotateFlip(nativeImage,
- rotateFlipType));
-}
-
-// Image property related functions
-
-inline UINT
-Image::GetPropertyCount()
-{
- UINT numProperty = 0;
-
- SetStatus(DllExports::GdipGetPropertyCount(nativeImage,
- &numProperty));
-
- return numProperty;
-}
-
-inline Status
-Image::GetPropertyIdList(
- IN UINT numOfProperty,
- OUT PROPID* list
- )
-{
- return SetStatus(DllExports::GdipGetPropertyIdList(nativeImage,
- numOfProperty, list));
-}
-
-inline UINT
-Image::GetPropertyItemSize(
- IN PROPID propId
- )
-{
- UINT size = 0;
-
- SetStatus(DllExports::GdipGetPropertyItemSize(nativeImage,
- propId,
- &size));
-
- return size;
-}
-
-inline Status
-Image::GetPropertyItem(
- IN PROPID propId,
- IN UINT propSize,
- OUT PropertyItem* buffer
- )
-{
- return SetStatus(DllExports::GdipGetPropertyItem(nativeImage,
- propId, propSize, buffer));
-}
-
-inline Status
-Image::GetPropertySize(
- OUT UINT* totalBufferSize,
- OUT UINT* numProperties
- )
-{
- return SetStatus(DllExports::GdipGetPropertySize(nativeImage,
- totalBufferSize,
- numProperties));
-}
-
-inline Status
-Image::GetAllPropertyItems(
- IN UINT totalBufferSize,
- IN UINT numProperties,
- OUT PropertyItem* allItems
- )
-{
- if (allItems == NULL)
- {
- return SetStatus(InvalidParameter);
- }
- return SetStatus(DllExports::GdipGetAllPropertyItems(nativeImage,
- totalBufferSize,
- numProperties,
- allItems));
-}
-
-inline Status
-Image::RemovePropertyItem(
- IN PROPID propId
- )
-{
- return SetStatus(DllExports::GdipRemovePropertyItem(nativeImage, propId));
-}
-
-inline Status
-Image::SetPropertyItem(
- IN const PropertyItem* item
- )
-{
- return SetStatus(DllExports::GdipSetPropertyItem(nativeImage, item));
-}
-
-// Get/SetLayout
-// Support for Middle East localization (right-to-left mirroring)
-
-inline ImageLayout
-Image::GetLayout() const
-{
- ImageLayout layout;
-
- SetStatus(DllExports::GdipGetImageLayout(nativeImage, &layout));
-
- return layout;
-}
-
-inline Status
-Image::SetLayout(IN const ImageLayout layout)
-{
- return SetStatus(
- DllExports::GdipSetImageLayout(nativeImage, layout)
- );
-}
-
-inline Status
-Image::GetLastStatus() const
-{
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
-}
-
-inline
-Image::Image(GpImage *nativeImage, Status status)
-{
- SetNativeImage(nativeImage);
- lastResult = status;
-}
-
-inline VOID
-Image::SetNativeImage(GpImage *nativeImage)
-{
- this->nativeImage = nativeImage;
-}
-
-inline
-Bitmap::Bitmap(
- IN const WCHAR *filename,
- IN BOOL useEmbeddedColorManagement
- )
-{
- GpBitmap *bitmap = NULL;
-
- if(useEmbeddedColorManagement)
- {
- lastResult = DllExports::GdipCreateBitmapFromFileICM(filename, &bitmap);
- }
- else
- {
- lastResult = DllExports::GdipCreateBitmapFromFile(filename, &bitmap);
- }
-
- SetNativeImage(bitmap);
-}
-
-inline
-Bitmap::Bitmap(
- IN IStream *stream,
- IN BOOL useEmbeddedColorManagement
- )
-{
- GpBitmap *bitmap = NULL;
-
- if(useEmbeddedColorManagement)
- {
- lastResult = DllExports::GdipCreateBitmapFromStreamICM(stream, &bitmap);
- }
- else
- {
- lastResult = DllExports::GdipCreateBitmapFromStream(stream, &bitmap);
- }
-
- SetNativeImage(bitmap);
-}
-
-inline
-Bitmap::Bitmap(
- IN INT width,
- IN INT height,
- IN INT stride,
- IN PixelFormat format,
- IN BYTE *scan0
- )
-{
- GpBitmap *bitmap = NULL;
-
- lastResult = DllExports::GdipCreateBitmapFromScan0(width,
- height,
- stride,
- format,
- scan0,
- &bitmap);
-
- SetNativeImage(bitmap);
-}
-
-inline
-Bitmap::Bitmap(
- IN INT width,
- IN INT height,
- IN PixelFormat format
- )
-{
- GpBitmap *bitmap = NULL;
-
- lastResult = DllExports::GdipCreateBitmapFromScan0(width,
- height,
- 0,
- format,
- NULL,
- &bitmap);
-
- SetNativeImage(bitmap);
-}
-
-inline
-Bitmap::Bitmap(
- IN INT width,
- IN INT height,
- IN Graphics* target)
-{
- GpBitmap *bitmap = NULL;
-
- lastResult = DllExports::GdipCreateBitmapFromGraphics(width,
- height,
- target->nativeGraphics,
- &bitmap);
-
- SetNativeImage(bitmap);
-}
-
-inline
-Bitmap::Bitmap(
- IN IDirectDrawSurface7 * surface
- )
-{
- GpBitmap *bitmap = NULL;
-
- lastResult = DllExports::GdipCreateBitmapFromDirectDrawSurface(surface,
- &bitmap);
-
- SetNativeImage(bitmap);
-}
-
-inline
-Bitmap::Bitmap(
- IN const BITMAPINFO* gdiBitmapInfo,
- IN VOID* gdiBitmapData
- )
-{
- GpBitmap *bitmap = NULL;
-
- lastResult = DllExports::GdipCreateBitmapFromGdiDib(gdiBitmapInfo,
- gdiBitmapData,
- &bitmap);
-
- SetNativeImage(bitmap);
-}
-
-inline
-Bitmap::Bitmap(
- IN HBITMAP hbm,
- IN HPALETTE hpal
- )
-{
- GpBitmap *bitmap = NULL;
-
- lastResult = DllExports::GdipCreateBitmapFromHBITMAP(hbm, hpal, &bitmap);
-
- SetNativeImage(bitmap);
-}
-
-inline
-Bitmap::Bitmap(
- IN HICON hicon
- )
-{
- GpBitmap *bitmap = NULL;
-
- lastResult = DllExports::GdipCreateBitmapFromHICON(hicon, &bitmap);
-
- SetNativeImage(bitmap);
-}
-
-inline
-Bitmap::Bitmap(
- IN HINSTANCE hInstance,
- IN const WCHAR *bitmapName
- )
-{
- GpBitmap *bitmap = NULL;
-
- lastResult = DllExports::GdipCreateBitmapFromResource(hInstance,
- bitmapName,
- &bitmap);
-
- SetNativeImage(bitmap);
-}
-
-
-inline Bitmap*
-Bitmap::FromFile(
- IN const WCHAR *filename,
- IN BOOL useEmbeddedColorManagement
- )
-{
- return new Bitmap(
- filename,
- useEmbeddedColorManagement
- );
-}
-
-inline Bitmap*
-Bitmap::FromStream(
- IN IStream *stream,
- IN BOOL useEmbeddedColorManagement
- )
-{
- return new Bitmap(
- stream,
- useEmbeddedColorManagement
- );
-}
-
-inline Bitmap*
-Bitmap::FromDirectDrawSurface7(
- IN IDirectDrawSurface7* surface
- )
-{
- return new Bitmap(surface);
-}
-
-inline Bitmap*
-Bitmap::FromBITMAPINFO(
- IN const BITMAPINFO* gdiBitmapInfo,
- IN VOID* gdiBitmapData)
-{
- return new Bitmap(gdiBitmapInfo, gdiBitmapData);
-}
-
-inline Bitmap*
-Bitmap::FromHBITMAP(
- IN HBITMAP hbm,
- IN HPALETTE hpal
- )
-{
- return new Bitmap(hbm, hpal);
-}
-
-inline Bitmap*
-Bitmap::FromHICON(
- IN HICON hicon
- )
-{
- return new Bitmap(hicon);
-}
-
-inline Bitmap*
-Bitmap::FromResource(
- IN HINSTANCE hInstance,
- IN const WCHAR *bitmapName)
-{
- return new Bitmap(hInstance, bitmapName);
-}
-
-inline Status
-Bitmap::GetHBITMAP(
- IN const Color& colorBackground,
- OUT HBITMAP* hbmReturn
- )
-{
- return SetStatus(DllExports::GdipCreateHBITMAPFromBitmap(
- static_cast<GpBitmap*>(nativeImage),
- hbmReturn,
- colorBackground.GetValue()));
-}
-
-inline Status
-Bitmap::GetHICON(
- OUT HICON* hiconReturn
- )
-{
- return SetStatus(DllExports::GdipCreateHICONFromBitmap(
- static_cast<GpBitmap*>(nativeImage),
- hiconReturn));
-}
-
-inline Bitmap*
-Bitmap::Clone(
- IN const Rect& rect,
- IN PixelFormat format
- )
-{
- return Clone(rect.X, rect.Y, rect.Width, rect.Height, format);
-}
-
-inline Bitmap*
-Bitmap::Clone(
- IN INT x,
- IN INT y,
- IN INT width,
- IN INT height,
- IN PixelFormat format
- )
-{
- GpBitmap* gpdstBitmap = NULL;
- Bitmap* bitmap;
-
- lastResult = DllExports::GdipCloneBitmapAreaI(
- x,
- y,
- width,
- height,
- format,
- (GpBitmap *)nativeImage,
- &gpdstBitmap);
-
- if (lastResult == Ok)
- {
- bitmap = new Bitmap(gpdstBitmap);
-
- if (bitmap == NULL)
- {
- DllExports::GdipDisposeImage(gpdstBitmap);
- }
-
- return bitmap;
- }
- else
- return NULL;
-}
-
-inline Bitmap*
-Bitmap::Clone(
- IN const RectF& rect,
- IN PixelFormat format
- )
-{
- return Clone(rect.X, rect.Y, rect.Width, rect.Height, format);
-}
-
-inline Bitmap*
-Bitmap::Clone(
- IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height,
- IN PixelFormat format
- )
-{
- GpBitmap* gpdstBitmap = NULL;
- Bitmap* bitmap;
-
- SetStatus(DllExports::GdipCloneBitmapArea(
- x,
- y,
- width,
- height,
- format,
- (GpBitmap *)nativeImage,
- &gpdstBitmap));
-
- if (lastResult == Ok)
- {
- bitmap = new Bitmap(gpdstBitmap);
-
- if (bitmap == NULL)
- {
- DllExports::GdipDisposeImage(gpdstBitmap);
- }
-
- return bitmap;
- }
- else
- return NULL;
-}
-
-inline Bitmap::Bitmap(GpBitmap *nativeBitmap)
-{
- lastResult = Ok;
-
- SetNativeImage(nativeBitmap);
-}
-
-inline Status
-Bitmap::LockBits(
- IN const Rect& rect,
- IN UINT flags,
- IN PixelFormat format,
- OUT BitmapData* lockedBitmapData
-)
-{
- return SetStatus(DllExports::GdipBitmapLockBits(
- static_cast<GpBitmap*>(nativeImage),
- &rect,
- flags,
- format,
- lockedBitmapData));
-}
-
-inline Status
-Bitmap::UnlockBits(
- IN BitmapData* lockedBitmapData
- )
-{
- return SetStatus(DllExports::GdipBitmapUnlockBits(
- static_cast<GpBitmap*>(nativeImage),
- lockedBitmapData));
-}
-
-inline Status
-Bitmap::GetPixel(
- IN INT x,
- IN INT y,
- OUT Color *color)
-{
- ARGB argb;
-
- Status status = SetStatus(DllExports::GdipBitmapGetPixel(
- static_cast<GpBitmap *>(nativeImage),
- x, y,
- &argb));
-
- if (status == Ok)
- {
- color->SetValue(argb);
- }
-
- return status;
-}
-
-inline Status
-Bitmap::SetPixel(
- IN INT x,
- IN INT y,
- IN const Color& color)
-{
- return SetStatus(DllExports::GdipBitmapSetPixel(
- static_cast<GpBitmap *>(nativeImage),
- x, y,
- color.GetValue()));
-}
-
-inline Status
-Bitmap::SetResolution(
- IN REAL xdpi,
- IN REAL ydpi)
-{
- return SetStatus(DllExports::GdipBitmapSetResolution(
- static_cast<GpBitmap *>(nativeImage),
- xdpi, ydpi));
-}
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusBitmap.h
+*
+* Abstract:
+*
+* Bitmap related declarations
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSBITMAP_H
+#define _GDIPLUSBITMAP_H
+
+// NOTE:
+// Our current choice for the public API is to use constructors
+// instead of static load functions to create image objects.
+//
+// I've kept the static load functions here for now so that
+// existing test programs are not broken. But they should
+// eventually be taken out.
+
+#ifndef DCR_USE_NEW_140782
+
+inline
+Image::Image(
+ IN const WCHAR* filename
+ )
+{
+ nativeImage = NULL;
+ lastResult = DllExports::GdipLoadImageFromFile(filename, &nativeImage);
+}
+
+inline
+Image::Image(
+ IN IStream* stream
+ )
+{
+ nativeImage = NULL;
+ lastResult = DllExports::GdipLoadImageFromStream(stream, &nativeImage);
+}
+
+inline Image*
+Image::FromFile(
+ IN const WCHAR* filename
+ )
+{
+ return new Image(filename);
+}
+
+inline Image*
+Image::FromStream(
+ IN IStream* stream
+ )
+{
+ return new Image(stream);
+}
+
+#else
+
+inline
+Image::Image(
+ IN const WCHAR* filename,
+ IN BOOL useEmbeddedColorManagement
+ )
+{
+ nativeImage = NULL;
+ if(useEmbeddedColorManagement)
+ {
+ lastResult = DllExports::GdipLoadImageFromFileICM(
+ filename,
+ &nativeImage
+ );
+ }
+ else
+ {
+ lastResult = DllExports::GdipLoadImageFromFile(
+ filename,
+ &nativeImage
+ );
+ }
+}
+
+inline
+Image::Image(
+ IN IStream* stream,
+ IN BOOL useEmbeddedColorManagement
+ )
+{
+ nativeImage = NULL;
+ if(useEmbeddedColorManagement)
+ {
+ lastResult = DllExports::GdipLoadImageFromStreamICM(
+ stream,
+ &nativeImage
+ );
+ }
+ else
+ {
+ lastResult = DllExports::GdipLoadImageFromStream(
+ stream,
+ &nativeImage
+ );
+ }
+}
+
+inline Image*
+Image::FromFile(
+ IN const WCHAR* filename,
+ IN BOOL useEmbeddedColorManagement
+ )
+{
+ return new Image(
+ filename,
+ useEmbeddedColorManagement
+ );
+}
+
+inline Image*
+Image::FromStream(
+ IN IStream* stream,
+ IN BOOL useEmbeddedColorManagement
+ )
+{
+ return new Image(
+ stream,
+ useEmbeddedColorManagement
+ );
+}
+
+#endif
+
+inline
+Image::~Image()
+{
+ DllExports::GdipDisposeImage(nativeImage);
+}
+
+inline Image*
+Image::Clone()
+{
+ GpImage *cloneimage = NULL;
+
+ SetStatus(DllExports::GdipCloneImage(nativeImage, &cloneimage));
+
+ return new Image(cloneimage, lastResult);
+}
+
+// Encorder Parameter
+
+inline UINT
+Image::GetEncoderParameterListSize(
+ IN const CLSID* clsidEncoder
+ )
+{
+ UINT size = 0;
+
+ SetStatus(DllExports::GdipGetEncoderParameterListSize(nativeImage,
+ clsidEncoder,
+ &size));
+ return size;
+}
+
+inline Status
+Image::GetEncoderParameterList(
+ IN const CLSID* clsidEncoder,
+ IN UINT size,
+ OUT EncoderParameters* buffer
+ )
+{
+ return SetStatus(DllExports::GdipGetEncoderParameterList(nativeImage,
+ clsidEncoder,
+ size,
+ buffer));
+}
+
+// Save images
+
+inline Status
+Image::Save(
+ IN const WCHAR* filename,
+ IN const CLSID* clsidEncoder,
+ IN const EncoderParameters *encoderParams
+ )
+{
+ return SetStatus(DllExports::GdipSaveImageToFile(nativeImage,
+ filename,
+ clsidEncoder,
+ encoderParams));
+}
+
+inline Status
+Image::Save(
+ IN IStream* stream,
+ IN const CLSID* clsidEncoder,
+ IN const EncoderParameters *encoderParams
+ )
+{
+ return SetStatus(DllExports::GdipSaveImageToStream(nativeImage,
+ stream,
+ clsidEncoder,
+ encoderParams));
+}
+
+inline Status
+Image::SaveAdd(
+ IN const EncoderParameters *encoderParams
+ )
+{
+ return SetStatus(DllExports::GdipSaveAdd(nativeImage,
+ encoderParams));
+}
+
+inline Status
+Image::SaveAdd(
+ IN Image* newImage,
+ IN const EncoderParameters *encoderParams
+ )
+{
+ if ( newImage == NULL )
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ return SetStatus(DllExports::GdipSaveAddImage(nativeImage,
+ newImage->nativeImage,
+ encoderParams));
+}
+
+// Get size and type information
+inline ImageType
+Image::GetType() const
+{
+ ImageType type = ImageTypeUnknown;
+
+ SetStatus(DllExports::GdipGetImageType(nativeImage, &type));
+
+ return type;
+}
+
+inline Status
+Image::GetPhysicalDimension(
+ OUT SizeF* size
+ )
+{
+ if (size == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ REAL width, height;
+ Status status;
+
+ status = SetStatus(DllExports::GdipGetImageDimension(nativeImage,
+ &width, &height));
+
+ size->Width = width;
+ size->Height = height;
+
+ return status;
+}
+
+inline Status
+Image::GetBounds(
+ OUT RectF *srcRect,
+ OUT Unit *srcUnit
+ )
+{
+ return SetStatus(DllExports::GdipGetImageBounds(nativeImage,
+ srcRect, srcUnit));
+}
+
+inline UINT
+Image::GetWidth()
+{
+ UINT width = 0;
+
+ SetStatus(DllExports::GdipGetImageWidth(nativeImage, &width));
+
+ return width;
+}
+
+inline UINT
+Image::GetHeight()
+{
+ UINT height = 0;
+
+ SetStatus(DllExports::GdipGetImageHeight(nativeImage, &height));
+
+ return height;
+}
+
+inline REAL
+Image::GetHorizontalResolution()
+{
+ REAL resolution = 0.0f;
+
+ SetStatus(DllExports::GdipGetImageHorizontalResolution(nativeImage, &resolution));
+
+ return resolution;
+}
+
+inline REAL
+Image::GetVerticalResolution()
+{
+ REAL resolution = 0.0f;
+
+ SetStatus(DllExports::GdipGetImageVerticalResolution(nativeImage, &resolution));
+
+ return resolution;
+}
+
+inline UINT
+Image::GetFlags()
+{
+ UINT flags = 0;
+
+ SetStatus(DllExports::GdipGetImageFlags(nativeImage, &flags));
+
+ return flags;
+}
+
+inline Status
+Image::GetRawFormat(OUT GUID *format)
+{
+ return SetStatus(DllExports::GdipGetImageRawFormat(nativeImage, format));
+}
+
+inline PixelFormat
+Image::GetPixelFormat()
+{
+ PixelFormat format;
+
+ SetStatus(DllExports::GdipGetImagePixelFormat(nativeImage, &format));
+
+ return format;
+}
+
+inline INT
+Image::GetPaletteSize()
+{
+ INT size = 0;
+
+ SetStatus(DllExports::GdipGetImagePaletteSize(nativeImage, &size));
+
+ return size;
+}
+
+inline Status
+Image::GetPalette(
+ OUT ColorPalette *palette,
+ IN INT size
+)
+{
+ return SetStatus(DllExports::GdipGetImagePalette(nativeImage, palette, size));
+}
+
+inline Status
+Image::SetPalette(
+ IN const ColorPalette *palette
+ )
+{
+ return SetStatus(DllExports::GdipSetImagePalette(nativeImage, palette));
+}
+
+// Thumbnail support
+
+inline Image*
+Image::GetThumbnailImage(
+ IN UINT thumbWidth,
+ IN UINT thumbHeight,
+ IN GetThumbnailImageAbort callback,
+ IN VOID* callbackData
+ )
+{
+ GpImage *thumbimage = NULL;
+
+ SetStatus(DllExports::GdipGetImageThumbnail(nativeImage,
+ thumbWidth, thumbHeight,
+ &thumbimage,
+ callback, callbackData));
+
+ Image *newImage = new Image(thumbimage, lastResult);
+
+ if (newImage == NULL)
+ {
+ DllExports::GdipDisposeImage(thumbimage);
+ }
+
+ return newImage;
+}
+
+// Multi-frame support
+inline UINT
+Image::GetFrameDimensionsCount()
+{
+ UINT count = 0;
+
+ SetStatus(DllExports::GdipImageGetFrameDimensionsCount(nativeImage,
+ &count));
+
+ return count;
+}
+
+inline Status
+Image::GetFrameDimensionsList(
+ OUT GUID* dimensionIDs,
+ IN UINT count
+ )
+{
+ return SetStatus(DllExports::GdipImageGetFrameDimensionsList(nativeImage,
+ dimensionIDs,
+ count));
+}
+
+inline UINT
+Image::GetFrameCount(
+ IN const GUID* dimensionID
+ )
+{
+ UINT count = 0;
+
+ SetStatus(DllExports::GdipImageGetFrameCount(nativeImage,
+ dimensionID,
+ &count));
+ return count;
+}
+
+inline Status
+Image::SelectActiveFrame(
+ IN const GUID *dimensionID,
+ IN UINT frameIndex
+ )
+{
+ return SetStatus(DllExports::GdipImageSelectActiveFrame(nativeImage,
+ dimensionID,
+ frameIndex));
+}
+
+inline Status
+Image::RotateFlip(
+ IN RotateFlipType rotateFlipType
+ )
+{
+ return SetStatus(DllExports::GdipImageRotateFlip(nativeImage,
+ rotateFlipType));
+}
+
+// Image property related functions
+
+inline UINT
+Image::GetPropertyCount()
+{
+ UINT numProperty = 0;
+
+ SetStatus(DllExports::GdipGetPropertyCount(nativeImage,
+ &numProperty));
+
+ return numProperty;
+}
+
+inline Status
+Image::GetPropertyIdList(
+ IN UINT numOfProperty,
+ OUT PROPID* list
+ )
+{
+ return SetStatus(DllExports::GdipGetPropertyIdList(nativeImage,
+ numOfProperty, list));
+}
+
+inline UINT
+Image::GetPropertyItemSize(
+ IN PROPID propId
+ )
+{
+ UINT size = 0;
+
+ SetStatus(DllExports::GdipGetPropertyItemSize(nativeImage,
+ propId,
+ &size));
+
+ return size;
+}
+
+inline Status
+Image::GetPropertyItem(
+ IN PROPID propId,
+ IN UINT propSize,
+ OUT PropertyItem* buffer
+ )
+{
+ return SetStatus(DllExports::GdipGetPropertyItem(nativeImage,
+ propId, propSize, buffer));
+}
+
+inline Status
+Image::GetPropertySize(
+ OUT UINT* totalBufferSize,
+ OUT UINT* numProperties
+ )
+{
+ return SetStatus(DllExports::GdipGetPropertySize(nativeImage,
+ totalBufferSize,
+ numProperties));
+}
+
+inline Status
+Image::GetAllPropertyItems(
+ IN UINT totalBufferSize,
+ IN UINT numProperties,
+ OUT PropertyItem* allItems
+ )
+{
+ if (allItems == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+ return SetStatus(DllExports::GdipGetAllPropertyItems(nativeImage,
+ totalBufferSize,
+ numProperties,
+ allItems));
+}
+
+inline Status
+Image::RemovePropertyItem(
+ IN PROPID propId
+ )
+{
+ return SetStatus(DllExports::GdipRemovePropertyItem(nativeImage, propId));
+}
+
+inline Status
+Image::SetPropertyItem(
+ IN const PropertyItem* item
+ )
+{
+ return SetStatus(DllExports::GdipSetPropertyItem(nativeImage, item));
+}
+
+// Get/SetLayout
+// Support for Middle East localization (right-to-left mirroring)
+
+inline ImageLayout
+Image::GetLayout() const
+{
+ ImageLayout layout;
+
+ SetStatus(DllExports::GdipGetImageLayout(nativeImage, &layout));
+
+ return layout;
+}
+
+inline Status
+Image::SetLayout(IN const ImageLayout layout)
+{
+ return SetStatus(
+ DllExports::GdipSetImageLayout(nativeImage, layout)
+ );
+}
+
+inline Status
+Image::GetLastStatus() const
+{
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+}
+
+inline
+Image::Image(GpImage *nativeImage, Status status)
+{
+ SetNativeImage(nativeImage);
+ lastResult = status;
+}
+
+inline VOID
+Image::SetNativeImage(GpImage *nativeImage)
+{
+ this->nativeImage = nativeImage;
+}
+
+inline
+Bitmap::Bitmap(
+ IN const WCHAR *filename,
+ IN BOOL useEmbeddedColorManagement
+ )
+{
+ GpBitmap *bitmap = NULL;
+
+ if(useEmbeddedColorManagement)
+ {
+ lastResult = DllExports::GdipCreateBitmapFromFileICM(filename, &bitmap);
+ }
+ else
+ {
+ lastResult = DllExports::GdipCreateBitmapFromFile(filename, &bitmap);
+ }
+
+ SetNativeImage(bitmap);
+}
+
+inline
+Bitmap::Bitmap(
+ IN IStream *stream,
+ IN BOOL useEmbeddedColorManagement
+ )
+{
+ GpBitmap *bitmap = NULL;
+
+ if(useEmbeddedColorManagement)
+ {
+ lastResult = DllExports::GdipCreateBitmapFromStreamICM(stream, &bitmap);
+ }
+ else
+ {
+ lastResult = DllExports::GdipCreateBitmapFromStream(stream, &bitmap);
+ }
+
+ SetNativeImage(bitmap);
+}
+
+inline
+Bitmap::Bitmap(
+ IN INT width,
+ IN INT height,
+ IN INT stride,
+ IN PixelFormat format,
+ IN BYTE *scan0
+ )
+{
+ GpBitmap *bitmap = NULL;
+
+ lastResult = DllExports::GdipCreateBitmapFromScan0(width,
+ height,
+ stride,
+ format,
+ scan0,
+ &bitmap);
+
+ SetNativeImage(bitmap);
+}
+
+inline
+Bitmap::Bitmap(
+ IN INT width,
+ IN INT height,
+ IN PixelFormat format
+ )
+{
+ GpBitmap *bitmap = NULL;
+
+ lastResult = DllExports::GdipCreateBitmapFromScan0(width,
+ height,
+ 0,
+ format,
+ NULL,
+ &bitmap);
+
+ SetNativeImage(bitmap);
+}
+
+inline
+Bitmap::Bitmap(
+ IN INT width,
+ IN INT height,
+ IN Graphics* target)
+{
+ GpBitmap *bitmap = NULL;
+
+ lastResult = DllExports::GdipCreateBitmapFromGraphics(width,
+ height,
+ target->nativeGraphics,
+ &bitmap);
+
+ SetNativeImage(bitmap);
+}
+
+inline
+Bitmap::Bitmap(
+ IN IDirectDrawSurface7 * surface
+ )
+{
+ GpBitmap *bitmap = NULL;
+
+ lastResult = DllExports::GdipCreateBitmapFromDirectDrawSurface(surface,
+ &bitmap);
+
+ SetNativeImage(bitmap);
+}
+
+inline
+Bitmap::Bitmap(
+ IN const BITMAPINFO* gdiBitmapInfo,
+ IN VOID* gdiBitmapData
+ )
+{
+ GpBitmap *bitmap = NULL;
+
+ lastResult = DllExports::GdipCreateBitmapFromGdiDib(gdiBitmapInfo,
+ gdiBitmapData,
+ &bitmap);
+
+ SetNativeImage(bitmap);
+}
+
+inline
+Bitmap::Bitmap(
+ IN HBITMAP hbm,
+ IN HPALETTE hpal
+ )
+{
+ GpBitmap *bitmap = NULL;
+
+ lastResult = DllExports::GdipCreateBitmapFromHBITMAP(hbm, hpal, &bitmap);
+
+ SetNativeImage(bitmap);
+}
+
+inline
+Bitmap::Bitmap(
+ IN HICON hicon
+ )
+{
+ GpBitmap *bitmap = NULL;
+
+ lastResult = DllExports::GdipCreateBitmapFromHICON(hicon, &bitmap);
+
+ SetNativeImage(bitmap);
+}
+
+inline
+Bitmap::Bitmap(
+ IN HINSTANCE hInstance,
+ IN const WCHAR *bitmapName
+ )
+{
+ GpBitmap *bitmap = NULL;
+
+ lastResult = DllExports::GdipCreateBitmapFromResource(hInstance,
+ bitmapName,
+ &bitmap);
+
+ SetNativeImage(bitmap);
+}
+
+
+inline Bitmap*
+Bitmap::FromFile(
+ IN const WCHAR *filename,
+ IN BOOL useEmbeddedColorManagement
+ )
+{
+ return new Bitmap(
+ filename,
+ useEmbeddedColorManagement
+ );
+}
+
+inline Bitmap*
+Bitmap::FromStream(
+ IN IStream *stream,
+ IN BOOL useEmbeddedColorManagement
+ )
+{
+ return new Bitmap(
+ stream,
+ useEmbeddedColorManagement
+ );
+}
+
+inline Bitmap*
+Bitmap::FromDirectDrawSurface7(
+ IN IDirectDrawSurface7* surface
+ )
+{
+ return new Bitmap(surface);
+}
+
+inline Bitmap*
+Bitmap::FromBITMAPINFO(
+ IN const BITMAPINFO* gdiBitmapInfo,
+ IN VOID* gdiBitmapData)
+{
+ return new Bitmap(gdiBitmapInfo, gdiBitmapData);
+}
+
+inline Bitmap*
+Bitmap::FromHBITMAP(
+ IN HBITMAP hbm,
+ IN HPALETTE hpal
+ )
+{
+ return new Bitmap(hbm, hpal);
+}
+
+inline Bitmap*
+Bitmap::FromHICON(
+ IN HICON hicon
+ )
+{
+ return new Bitmap(hicon);
+}
+
+inline Bitmap*
+Bitmap::FromResource(
+ IN HINSTANCE hInstance,
+ IN const WCHAR *bitmapName)
+{
+ return new Bitmap(hInstance, bitmapName);
+}
+
+inline Status
+Bitmap::GetHBITMAP(
+ IN const Color& colorBackground,
+ OUT HBITMAP* hbmReturn
+ )
+{
+ return SetStatus(DllExports::GdipCreateHBITMAPFromBitmap(
+ static_cast<GpBitmap*>(nativeImage),
+ hbmReturn,
+ colorBackground.GetValue()));
+}
+
+inline Status
+Bitmap::GetHICON(
+ OUT HICON* hiconReturn
+ )
+{
+ return SetStatus(DllExports::GdipCreateHICONFromBitmap(
+ static_cast<GpBitmap*>(nativeImage),
+ hiconReturn));
+}
+
+inline Bitmap*
+Bitmap::Clone(
+ IN const Rect& rect,
+ IN PixelFormat format
+ )
+{
+ return Clone(rect.X, rect.Y, rect.Width, rect.Height, format);
+}
+
+inline Bitmap*
+Bitmap::Clone(
+ IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height,
+ IN PixelFormat format
+ )
+{
+ GpBitmap* gpdstBitmap = NULL;
+ Bitmap* bitmap;
+
+ lastResult = DllExports::GdipCloneBitmapAreaI(
+ x,
+ y,
+ width,
+ height,
+ format,
+ (GpBitmap *)nativeImage,
+ &gpdstBitmap);
+
+ if (lastResult == Ok)
+ {
+ bitmap = new Bitmap(gpdstBitmap);
+
+ if (bitmap == NULL)
+ {
+ DllExports::GdipDisposeImage(gpdstBitmap);
+ }
+
+ return bitmap;
+ }
+ else
+ return NULL;
+}
+
+inline Bitmap*
+Bitmap::Clone(
+ IN const RectF& rect,
+ IN PixelFormat format
+ )
+{
+ return Clone(rect.X, rect.Y, rect.Width, rect.Height, format);
+}
+
+inline Bitmap*
+Bitmap::Clone(
+ IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height,
+ IN PixelFormat format
+ )
+{
+ GpBitmap* gpdstBitmap = NULL;
+ Bitmap* bitmap;
+
+ SetStatus(DllExports::GdipCloneBitmapArea(
+ x,
+ y,
+ width,
+ height,
+ format,
+ (GpBitmap *)nativeImage,
+ &gpdstBitmap));
+
+ if (lastResult == Ok)
+ {
+ bitmap = new Bitmap(gpdstBitmap);
+
+ if (bitmap == NULL)
+ {
+ DllExports::GdipDisposeImage(gpdstBitmap);
+ }
+
+ return bitmap;
+ }
+ else
+ return NULL;
+}
+
+inline Bitmap::Bitmap(GpBitmap *nativeBitmap)
+{
+ lastResult = Ok;
+
+ SetNativeImage(nativeBitmap);
+}
+
+inline Status
+Bitmap::LockBits(
+ IN const Rect& rect,
+ IN UINT flags,
+ IN PixelFormat format,
+ OUT BitmapData* lockedBitmapData
+)
+{
+ return SetStatus(DllExports::GdipBitmapLockBits(
+ static_cast<GpBitmap*>(nativeImage),
+ &rect,
+ flags,
+ format,
+ lockedBitmapData));
+}
+
+inline Status
+Bitmap::UnlockBits(
+ IN BitmapData* lockedBitmapData
+ )
+{
+ return SetStatus(DllExports::GdipBitmapUnlockBits(
+ static_cast<GpBitmap*>(nativeImage),
+ lockedBitmapData));
+}
+
+inline Status
+Bitmap::GetPixel(
+ IN INT x,
+ IN INT y,
+ OUT Color *color)
+{
+ ARGB argb;
+
+ Status status = SetStatus(DllExports::GdipBitmapGetPixel(
+ static_cast<GpBitmap *>(nativeImage),
+ x, y,
+ &argb));
+
+ if (status == Ok)
+ {
+ color->SetValue(argb);
+ }
+
+ return status;
+}
+
+inline Status
+Bitmap::SetPixel(
+ IN INT x,
+ IN INT y,
+ IN const Color& color)
+{
+ return SetStatus(DllExports::GdipBitmapSetPixel(
+ static_cast<GpBitmap *>(nativeImage),
+ x, y,
+ color.GetValue()));
+}
+
+inline Status
+Bitmap::SetResolution(
+ IN REAL xdpi,
+ IN REAL ydpi)
+{
+ return SetStatus(DllExports::GdipBitmapSetResolution(
+ static_cast<GpBitmap *>(nativeImage),
+ xdpi, ydpi));
+}
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusBrush.h b/core/src/fxge/Microsoft SDK/include/GdiPlusBrush.h
index a506f87982..c25e34ae01 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusBrush.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusBrush.h
@@ -1,951 +1,951 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusBrush.h
-*
-* Abstract:
-*
-* Brush API related declarations
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSBRUSH_H
-#define _GDIPLUSBRUSH_H
-
-//--------------------------------------------------------------------------
-// Abstract base class for various brush types
-//--------------------------------------------------------------------------
-
-class GraphicsPath;
-
-class Brush : public GdiplusBase
-{
-public:
- friend class Pen;
- friend class Graphics;
-
- virtual ~Brush()
- {
- DllExports::GdipDeleteBrush(nativeBrush);
- }
-
- virtual Brush* Clone() const
- {
- GpBrush *brush = NULL;
-
- SetStatus(DllExports::GdipCloneBrush(nativeBrush, &brush));
-
- Brush *newBrush = new Brush(brush, lastResult);
-
- if (newBrush == NULL)
- {
- DllExports::GdipDeleteBrush(brush);
- }
-
- return newBrush;
- }
-
- BrushType GetType() const
- {
- BrushType type = static_cast<BrushType>(-1);
-
- SetStatus(DllExports::GdipGetBrushType(nativeBrush, &type));
-
- return type;
- }
-
- Status GetLastStatus() const
- {
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
- }
-
-protected:
-
- Brush()
- {
- SetStatus(NotImplemented);
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- Brush(const Brush& brush);
- Brush& operator=(const Brush& brush);
-protected:
-
-#else
-
- Brush(const Brush& brush)
- {
- brush;
- SetStatus(NotImplemented);
- }
-
- Brush& operator=(const Brush& brush)
- {
- brush;
- SetStatus(NotImplemented);
- return *this;
- }
-
-#endif
-
- Brush(GpBrush* nativeBrush, Status status)
- {
- lastResult = status;
- SetNativeBrush(nativeBrush);
- }
-
- VOID SetNativeBrush(GpBrush* nativeBrush)
- {
- this->nativeBrush = nativeBrush;
- }
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
- GpBrush* nativeBrush;
- mutable Status lastResult;
-};
-
-//--------------------------------------------------------------------------
-// Represent solid fill brush object
-//--------------------------------------------------------------------------
-
-class SolidBrush : public Brush
-{
-public:
- friend class Pen;
-
- SolidBrush(IN const Color& color)
- {
- GpSolidFill *brush = NULL;
-
- lastResult = DllExports::GdipCreateSolidFill(color.GetValue(), &brush);
-
- SetNativeBrush(brush);
- }
-
- Status GetColor(OUT Color* color) const
- {
- ARGB argb;
-
- if (color == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- SetStatus(DllExports::GdipGetSolidFillColor((GpSolidFill*)nativeBrush,
- &argb));
-
- *color = Color(argb);
-
- return lastResult;
- }
-
- Status SetColor(IN const Color& color)
- {
- return SetStatus(DllExports::GdipSetSolidFillColor((GpSolidFill*)nativeBrush,
- color.GetValue()));
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- SolidBrush(const SolidBrush &);
- SolidBrush& operator=(const SolidBrush &);
-
-#endif
-
-protected:
-
- SolidBrush()
- {
- }
-};
-
-class TextureBrush : public Brush
-{
-public:
- friend class Pen;
-
- TextureBrush(IN Image* image,
- IN WrapMode wrapMode = WrapModeTile)
- {
- GpTexture *texture = NULL;
-
- lastResult = DllExports::GdipCreateTexture(
- image->nativeImage,
- wrapMode, &texture);
-
- SetNativeBrush(texture);
- }
-
- // When creating a texture brush from a metafile image, the dstRect
- // is used to specify the size that the metafile image should be
- // rendered at in the device units of the destination graphics.
- // It is NOT used to crop the metafile image, so only the width
- // and height values matter for metafiles.
- TextureBrush(IN Image* image,
- IN WrapMode wrapMode,
- IN const RectF &dstRect)
- {
- GpTexture *texture = NULL;
-
- lastResult = DllExports::GdipCreateTexture2(
- image->nativeImage,
- wrapMode,
- dstRect.X,
- dstRect.Y,
- dstRect.Width,
- dstRect.Height,
- &texture);
-
- SetNativeBrush(texture);
- }
-
- // When creating a texture brush from a metafile image, the dstRect
- // is used to specify the size that the metafile image should be
- // rendered at in the device units of the destination graphics.
- // It is NOT used to crop the metafile image, so only the width
- // and height values matter for metafiles.
-
- TextureBrush(IN Image *image,
- IN const RectF &dstRect,
- IN const ImageAttributes *imageAttributes = NULL)
- {
- GpTexture *texture = NULL;
-
- lastResult = DllExports::GdipCreateTextureIA(
- image->nativeImage,
- (imageAttributes)?imageAttributes->nativeImageAttr:NULL,
- dstRect.X,
- dstRect.Y,
- dstRect.Width,
- dstRect.Height,
- &texture
- );
-
- SetNativeBrush(texture);
- }
-
- #ifdef DCR_USE_NEW_145138
- TextureBrush(IN Image *image,
- IN const Rect &dstRect,
- IN const ImageAttributes *imageAttributes = NULL)
- {
- GpTexture *texture = NULL;
-
- lastResult = DllExports::GdipCreateTextureIAI(
- image->nativeImage,
- (imageAttributes)?imageAttributes->nativeImageAttr:NULL,
- dstRect.X,
- dstRect.Y,
- dstRect.Width,
- dstRect.Height,
- &texture
- );
-
- SetNativeBrush(texture);
- }
- #endif
-
- // When creating a texture brush from a metafile image, the dstRect
- // is used to specify the size that the metafile image should be
- // rendered at in the device units of the destination graphics.
- // It is NOT used to crop the metafile image, so only the width
- // and height values matter for metafiles.
-
- TextureBrush(
- IN Image* image,
- IN WrapMode wrapMode,
-
- #ifdef DCR_USE_NEW_145138
- const IN Rect &dstRect
- #else
- IN Rect &dstRect
- #endif
- )
- {
- GpTexture *texture = NULL;
-
- lastResult = DllExports::GdipCreateTexture2I(
- image->nativeImage,
- wrapMode,
- dstRect.X,
- dstRect.Y,
- dstRect.Width,
- dstRect.Height,
- &texture);
-
- SetNativeBrush(texture);
- }
-
- // When creating a texture brush from a metafile image, the dstRect
- // is used to specify the size that the metafile image should be
- // rendered at in the device units of the destination graphics.
- // It is NOT used to crop the metafile image, so only the width
- // and height values matter for metafiles.
- TextureBrush(IN Image* image,
- IN WrapMode wrapMode,
- IN REAL dstX,
- IN REAL dstY,
- IN REAL dstWidth,
- IN REAL dstHeight)
- {
- GpTexture *texture = NULL;
-
- lastResult = DllExports::GdipCreateTexture2(
- image->nativeImage,
- wrapMode,
- dstX,
- dstY,
- dstWidth,
- dstHeight,
- &texture);
-
- SetNativeBrush(texture);
- }
-
- // When creating a texture brush from a metafile image, the dstRect
- // is used to specify the size that the metafile image should be
- // rendered at in the device units of the destination graphics.
- // It is NOT used to crop the metafile image, so only the width
- // and height values matter for metafiles.
- TextureBrush(IN Image* image,
- IN WrapMode wrapMode,
- IN INT dstX,
- IN INT dstY,
- IN INT dstWidth,
- IN INT dstHeight)
- {
- GpTexture *texture = NULL;
-
- lastResult = DllExports::GdipCreateTexture2I(
- image->nativeImage,
- wrapMode,
- dstX,
- dstY,
- dstWidth,
- dstHeight,
- &texture);
-
- SetNativeBrush(texture);
- }
-
- /**
- * Set/get brush transform
- */
- Status SetTransform(IN const Matrix* matrix)
- {
- return SetStatus(DllExports::GdipSetTextureTransform((GpTexture*)nativeBrush,
- matrix->nativeMatrix));
- }
-
- Status GetTransform(OUT Matrix* matrix) const
- {
- return SetStatus(DllExports::GdipGetTextureTransform((GpTexture*)nativeBrush,
- matrix->nativeMatrix));
- }
-
- Status ResetTransform()
- {
- return SetStatus(DllExports::GdipResetTextureTransform((GpTexture*)nativeBrush));
- }
-
- Status MultiplyTransform(IN const Matrix* matrix,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipMultiplyTextureTransform((GpTexture*)nativeBrush,
- matrix->nativeMatrix,
- order));
- }
-
- Status TranslateTransform(IN REAL dx,
- IN REAL dy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipTranslateTextureTransform((GpTexture*)nativeBrush,
- dx, dy, order));
- }
-
- Status ScaleTransform(IN REAL sx,
- IN REAL sy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipScaleTextureTransform((GpTexture*)nativeBrush,
- sx, sy, order));
- }
-
- Status RotateTransform(IN REAL angle,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipRotateTextureTransform((GpTexture*)nativeBrush,
- angle, order));
- }
-
- /**
- * Set/get brush wrapping mode
- */
- Status SetWrapMode(IN WrapMode wrapMode)
- {
- return SetStatus(DllExports::GdipSetTextureWrapMode((GpTexture*)nativeBrush,
- wrapMode));
- }
-
- WrapMode GetWrapMode() const
- {
- WrapMode wrapMode;
-
- SetStatus(DllExports::GdipGetTextureWrapMode((GpTexture*)nativeBrush,
- &wrapMode));
- return wrapMode;
- }
-
- // Get texture brush attributes
-
- Image *GetImage() const
- {
- GpImage *image;
-
- SetStatus(DllExports::GdipGetTextureImage((GpTexture *)nativeBrush,
- &image));
-
- Image *retimage = new Image(image, lastResult);
-
- if (retimage == NULL)
- {
- DllExports::GdipDisposeImage(image);
- }
-
- return retimage;
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- TextureBrush(const TextureBrush &);
- TextureBrush& operator=(const TextureBrush &);
-
-#endif
-
-protected:
-
- TextureBrush()
- {
- }
-};
-
-//--------------------------------------------------------------------------
-// Represent line gradient brush object
-//--------------------------------------------------------------------------
-
-class LinearGradientBrush : public Brush
-{
-public:
- friend class Pen;
-
- LinearGradientBrush(IN const PointF& point1,
- IN const PointF& point2,
- IN const Color& color1,
- IN const Color& color2)
- {
- GpLineGradient *brush = NULL;
-
- lastResult = DllExports::GdipCreateLineBrush(&point1,
- &point2,
- color1.GetValue(),
- color2.GetValue(),
- WrapModeTile,
- &brush);
-
- SetNativeBrush(brush);
- }
-
- LinearGradientBrush(IN const Point& point1,
- IN const Point& point2,
- IN const Color& color1,
- IN const Color& color2)
- {
- GpLineGradient *brush = NULL;
-
- lastResult = DllExports::GdipCreateLineBrushI(&point1,
- &point2,
- color1.GetValue(),
- color2.GetValue(),
- WrapModeTile,
- &brush);
-
- SetNativeBrush(brush);
- }
-
- LinearGradientBrush(IN const RectF& rect,
- IN const Color& color1,
- IN const Color& color2,
- IN LinearGradientMode mode)
- {
- GpLineGradient *brush = NULL;
-
- lastResult = DllExports::GdipCreateLineBrushFromRect(&rect,
- color1.GetValue(),
- color2.GetValue(),
- mode,
- WrapModeTile,
- &brush);
-
- SetNativeBrush(brush);
- }
-
- LinearGradientBrush(IN const Rect& rect,
- IN const Color& color1,
- IN const Color& color2,
- IN LinearGradientMode mode)
- {
- GpLineGradient *brush = NULL;
-
- lastResult = DllExports::GdipCreateLineBrushFromRectI(&rect,
- color1.GetValue(),
- color2.GetValue(),
- mode,
- WrapModeTile,
- &brush);
-
- SetNativeBrush(brush);
- }
-
- LinearGradientBrush(IN const RectF& rect,
- IN const Color& color1,
- IN const Color& color2,
- IN REAL angle,
- IN BOOL isAngleScalable = FALSE)
- {
- GpLineGradient *brush = NULL;
-
- lastResult = DllExports::GdipCreateLineBrushFromRectWithAngle(&rect,
- color1.GetValue(),
- color2.GetValue(),
- angle,
- isAngleScalable,
- WrapModeTile,
- &brush);
-
- SetNativeBrush(brush);
- }
-
- LinearGradientBrush(IN const Rect& rect,
- IN const Color& color1,
- IN const Color& color2,
- IN REAL angle,
- IN BOOL isAngleScalable = FALSE)
- {
- GpLineGradient *brush = NULL;
-
- lastResult = DllExports::GdipCreateLineBrushFromRectWithAngleI(&rect,
- color1.GetValue(),
- color2.GetValue(),
- angle,
- isAngleScalable,
- WrapModeTile,
- &brush);
-
- SetNativeBrush(brush);
- }
-
- // Get/set point attributes
-
- Status SetLinearPoints(IN const PointF& point1,
- IN const PointF& point2)
- {
- return SetStatus(DllExports::GdipSetLinePoints((GpLineGradient*)nativeBrush,
- &point1, &point2));
- }
-
- Status GetLinearPoints(OUT PointF* points) const
- {
- return SetStatus(DllExports::GdipGetLinePoints((GpLineGradient*) nativeBrush,
- points));
- }
-
- Status SetLinearPoints(IN const Point& point1,
- IN const Point& point2)
- {
- return SetStatus(DllExports::GdipSetLinePointsI((GpLineGradient*)nativeBrush,
- &point1, &point2));
- }
-
- Status GetLinearPoints(OUT Point* points) const
- {
- return SetStatus(DllExports::GdipGetLinePointsI((GpLineGradient*) nativeBrush,
- points));
- }
- // Get/set color attributes
-
- Status SetLinearColors(IN const Color& color1,
- IN const Color& color2)
- {
- return SetStatus(DllExports::GdipSetLineColors((GpLineGradient*)nativeBrush,
- color1.GetValue(),
- color2.GetValue()));
- }
-
- Status GetLinearColors(OUT Color* colors) const
- {
- ARGB argb[2];
-
- if (colors == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- SetStatus(DllExports::GdipGetLineColors((GpLineGradient*) nativeBrush, argb));
-
- if (lastResult == Ok)
- {
- // use bitwise copy operator for Color copy
- colors[0] = Color(argb[0]);
- colors[1] = Color(argb[1]);
- }
-
- return lastResult;
- }
-
- Status GetRectangle(OUT RectF* rect) const
- {
- return SetStatus(DllExports::GdipGetLineRect((GpLineGradient*)nativeBrush, rect));
- }
-
- // integer version
- Status GetRectangle(OUT Rect* rect) const
- {
- return SetStatus(DllExports::GdipGetLineRectI((GpLineGradient*)nativeBrush, rect));
- }
-
- // Gamma correction in interporlation.
-
- Status SetGammaCorrection(IN BOOL useGammaCorrection)
- {
- return SetStatus(DllExports::GdipSetLineGammaCorrection((GpLineGradient*)nativeBrush,
- useGammaCorrection));
- }
-
- BOOL GetGammaCorrection() const
- {
- BOOL useGammaCorrection;
-
- SetStatus(DllExports::GdipGetLineGammaCorrection((GpLineGradient*)nativeBrush,
- &useGammaCorrection));
-
- return useGammaCorrection;
- }
-
- INT GetBlendCount() const
- {
- INT count = 0;
-
- SetStatus(DllExports::GdipGetLineBlendCount((GpLineGradient*)
- nativeBrush,
- &count));
-
- return count;
- }
-
- Status SetBlend(IN const REAL* blendFactors,
- IN const REAL* blendPositions,
- IN INT count)
- {
- return SetStatus(DllExports::GdipSetLineBlend((GpLineGradient*)
- nativeBrush,
- blendFactors,
- blendPositions,
- count));
- }
-
- Status GetBlend(OUT REAL* blendFactors,
- OUT REAL* blendPositions,
- IN INT count) const
- {
- return SetStatus(DllExports::GdipGetLineBlend((GpLineGradient*)nativeBrush,
- blendFactors,
- blendPositions,
- count));
- }
-
- INT GetInterpolationColorCount() const
- {
- INT count = 0;
-
- SetStatus(DllExports::GdipGetLinePresetBlendCount((GpLineGradient*)
- nativeBrush,
- &count));
-
- return count;
- }
-
- Status SetInterpolationColors(IN const Color* presetColors,
- IN const REAL* blendPositions,
- IN INT count)
- {
- if ((count <= 0) || !presetColors)
- return SetStatus(InvalidParameter);
-
- ARGB *argbs = (ARGB*) new BYTE[count*sizeof(ARGB)];
-
- if (argbs)
- {
- for (INT i = 0; i < count; i++)
- {
- argbs[i] = presetColors[i].GetValue();
- }
-
- Status status = SetStatus(DllExports::GdipSetLinePresetBlend(
- (GpLineGradient*) nativeBrush,
- argbs,
- blendPositions,
- count));
- delete [] argbs;
- return status;
- }
- else
- {
- return SetStatus(OutOfMemory);
- }
- }
-
- Status GetInterpolationColors(OUT Color* presetColors,
- OUT REAL* blendPositions,
- IN INT count) const
- {
- if ((count <= 0) || !presetColors)
- return SetStatus(InvalidParameter);
-
- ARGB* argbs = (ARGB*) new BYTE[count*sizeof(ARGB)];
-
- if (!argbs)
- {
- return SetStatus(OutOfMemory);
- }
-
- Status status = SetStatus(DllExports::GdipGetLinePresetBlend((GpLineGradient*)nativeBrush,
- argbs,
- blendPositions,
- count));
- if (status == Ok)
- {
- for (INT i = 0; i < count; i++)
- {
- presetColors[i] = Color(argbs[i]);
- }
- }
-
- delete [] argbs;
-
- return status;
- }
-
- Status SetBlendBellShape(IN REAL focus,
- IN REAL scale = 1.0)
- {
- return SetStatus(DllExports::GdipSetLineSigmaBlend((GpLineGradient*)nativeBrush, focus, scale));
- }
-
- #ifdef DCR_USE_NEW_145135
- Status SetBlendTriangularShape(
- IN REAL focus,
- IN REAL scale = 1.0
- )
- #else
- Status SetBlendTrianglarShape(IN REAL focus,
- IN REAL scale = 1.0)
- #endif
- {
- return SetStatus(DllExports::GdipSetLineLinearBlend((GpLineGradient*)nativeBrush, focus, scale));
- }
-
- /**
- * Set/get brush transform
- */
- Status SetTransform(IN const Matrix* matrix)
- {
- return SetStatus(DllExports::GdipSetLineTransform((GpLineGradient*)nativeBrush,
- matrix->nativeMatrix));
- }
-
- Status GetTransform(OUT Matrix *matrix) const
- {
- return SetStatus(DllExports::GdipGetLineTransform((GpLineGradient*)nativeBrush,
- matrix->nativeMatrix));
- }
-
- Status ResetTransform()
- {
- return SetStatus(DllExports::GdipResetLineTransform((GpLineGradient*)nativeBrush));
- }
-
- Status MultiplyTransform(IN const Matrix* matrix,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipMultiplyLineTransform((GpLineGradient*)nativeBrush,
- matrix->nativeMatrix,
- order));
- }
-
- Status TranslateTransform(IN REAL dx,
- IN REAL dy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipTranslateLineTransform((GpLineGradient*)nativeBrush,
- dx, dy, order));
- }
-
- Status ScaleTransform(IN REAL sx,
- IN REAL sy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipScaleLineTransform((GpLineGradient*)nativeBrush,
- sx, sy, order));
- }
-
- Status RotateTransform(IN REAL angle,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipRotateLineTransform((GpLineGradient*)nativeBrush,
- angle, order));
- }
-
- /**
- * Set/get brush wrapping mode
- */
- Status SetWrapMode(IN WrapMode wrapMode)
- {
- return SetStatus(DllExports::GdipSetLineWrapMode((GpLineGradient*)nativeBrush,
- wrapMode));
- }
-
- WrapMode GetWrapMode() const
- {
- WrapMode wrapMode;
-
- SetStatus(DllExports::GdipGetLineWrapMode((GpLineGradient*)
- nativeBrush,
- &wrapMode));
-
- return wrapMode;
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- LinearGradientBrush(const LinearGradientBrush &);
- LinearGradientBrush& operator=(const LinearGradientBrush &);
-
-#endif
-
-protected:
-
- LinearGradientBrush()
- {
- }
-};
-
-//--------------------------------------------------------------------------
-// PathGradientBrush object is defined
-// in gdipluspath.h.
-//--------------------------------------------------------------------------
-
-//--------------------------------------------------------------------------
-// Represent hatch brush object
-//--------------------------------------------------------------------------
-
-class HatchBrush : public Brush
-{
-public:
- friend class Pen;
-
- // Constructors
-
- HatchBrush(IN HatchStyle hatchStyle,
- IN const Color& foreColor,
- IN const Color& backColor = Color())
- {
- GpHatch *brush = NULL;
-
- lastResult = DllExports::GdipCreateHatchBrush(hatchStyle,
- foreColor.GetValue(),
- backColor.GetValue(),
- &brush);
- SetNativeBrush(brush);
- }
-
- HatchStyle GetHatchStyle() const
- {
- HatchStyle hatchStyle;
-
- SetStatus(DllExports::GdipGetHatchStyle((GpHatch*)nativeBrush,
- &hatchStyle));
-
- return hatchStyle;
- }
-
- Status GetForegroundColor(OUT Color* color) const
- {
- ARGB argb;
-
- if (color == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- Status status = SetStatus(DllExports::GdipGetHatchForegroundColor(
- (GpHatch*)nativeBrush,
- &argb));
-
- color->SetValue(argb);
-
- return status;
- }
-
- Status GetBackgroundColor(OUT Color *color) const
- {
- ARGB argb;
-
- if (color == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- Status status = SetStatus(DllExports::GdipGetHatchBackgroundColor(
- (GpHatch*)nativeBrush,
- &argb));
-
- color->SetValue(argb);
-
- return status;
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- HatchBrush(const HatchBrush &);
- HatchBrush& operator=(const HatchBrush &);
-
-#endif
-
-protected:
-
- HatchBrush()
- {
- }
-};
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusBrush.h
+*
+* Abstract:
+*
+* Brush API related declarations
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSBRUSH_H
+#define _GDIPLUSBRUSH_H
+
+//--------------------------------------------------------------------------
+// Abstract base class for various brush types
+//--------------------------------------------------------------------------
+
+class GraphicsPath;
+
+class Brush : public GdiplusBase
+{
+public:
+ friend class Pen;
+ friend class Graphics;
+
+ virtual ~Brush()
+ {
+ DllExports::GdipDeleteBrush(nativeBrush);
+ }
+
+ virtual Brush* Clone() const
+ {
+ GpBrush *brush = NULL;
+
+ SetStatus(DllExports::GdipCloneBrush(nativeBrush, &brush));
+
+ Brush *newBrush = new Brush(brush, lastResult);
+
+ if (newBrush == NULL)
+ {
+ DllExports::GdipDeleteBrush(brush);
+ }
+
+ return newBrush;
+ }
+
+ BrushType GetType() const
+ {
+ BrushType type = static_cast<BrushType>(-1);
+
+ SetStatus(DllExports::GdipGetBrushType(nativeBrush, &type));
+
+ return type;
+ }
+
+ Status GetLastStatus() const
+ {
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+ }
+
+protected:
+
+ Brush()
+ {
+ SetStatus(NotImplemented);
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ Brush(const Brush& brush);
+ Brush& operator=(const Brush& brush);
+protected:
+
+#else
+
+ Brush(const Brush& brush)
+ {
+ brush;
+ SetStatus(NotImplemented);
+ }
+
+ Brush& operator=(const Brush& brush)
+ {
+ brush;
+ SetStatus(NotImplemented);
+ return *this;
+ }
+
+#endif
+
+ Brush(GpBrush* nativeBrush, Status status)
+ {
+ lastResult = status;
+ SetNativeBrush(nativeBrush);
+ }
+
+ VOID SetNativeBrush(GpBrush* nativeBrush)
+ {
+ this->nativeBrush = nativeBrush;
+ }
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+ GpBrush* nativeBrush;
+ mutable Status lastResult;
+};
+
+//--------------------------------------------------------------------------
+// Represent solid fill brush object
+//--------------------------------------------------------------------------
+
+class SolidBrush : public Brush
+{
+public:
+ friend class Pen;
+
+ SolidBrush(IN const Color& color)
+ {
+ GpSolidFill *brush = NULL;
+
+ lastResult = DllExports::GdipCreateSolidFill(color.GetValue(), &brush);
+
+ SetNativeBrush(brush);
+ }
+
+ Status GetColor(OUT Color* color) const
+ {
+ ARGB argb;
+
+ if (color == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ SetStatus(DllExports::GdipGetSolidFillColor((GpSolidFill*)nativeBrush,
+ &argb));
+
+ *color = Color(argb);
+
+ return lastResult;
+ }
+
+ Status SetColor(IN const Color& color)
+ {
+ return SetStatus(DllExports::GdipSetSolidFillColor((GpSolidFill*)nativeBrush,
+ color.GetValue()));
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ SolidBrush(const SolidBrush &);
+ SolidBrush& operator=(const SolidBrush &);
+
+#endif
+
+protected:
+
+ SolidBrush()
+ {
+ }
+};
+
+class TextureBrush : public Brush
+{
+public:
+ friend class Pen;
+
+ TextureBrush(IN Image* image,
+ IN WrapMode wrapMode = WrapModeTile)
+ {
+ GpTexture *texture = NULL;
+
+ lastResult = DllExports::GdipCreateTexture(
+ image->nativeImage,
+ wrapMode, &texture);
+
+ SetNativeBrush(texture);
+ }
+
+ // When creating a texture brush from a metafile image, the dstRect
+ // is used to specify the size that the metafile image should be
+ // rendered at in the device units of the destination graphics.
+ // It is NOT used to crop the metafile image, so only the width
+ // and height values matter for metafiles.
+ TextureBrush(IN Image* image,
+ IN WrapMode wrapMode,
+ IN const RectF &dstRect)
+ {
+ GpTexture *texture = NULL;
+
+ lastResult = DllExports::GdipCreateTexture2(
+ image->nativeImage,
+ wrapMode,
+ dstRect.X,
+ dstRect.Y,
+ dstRect.Width,
+ dstRect.Height,
+ &texture);
+
+ SetNativeBrush(texture);
+ }
+
+ // When creating a texture brush from a metafile image, the dstRect
+ // is used to specify the size that the metafile image should be
+ // rendered at in the device units of the destination graphics.
+ // It is NOT used to crop the metafile image, so only the width
+ // and height values matter for metafiles.
+
+ TextureBrush(IN Image *image,
+ IN const RectF &dstRect,
+ IN const ImageAttributes *imageAttributes = NULL)
+ {
+ GpTexture *texture = NULL;
+
+ lastResult = DllExports::GdipCreateTextureIA(
+ image->nativeImage,
+ (imageAttributes)?imageAttributes->nativeImageAttr:NULL,
+ dstRect.X,
+ dstRect.Y,
+ dstRect.Width,
+ dstRect.Height,
+ &texture
+ );
+
+ SetNativeBrush(texture);
+ }
+
+ #ifdef DCR_USE_NEW_145138
+ TextureBrush(IN Image *image,
+ IN const Rect &dstRect,
+ IN const ImageAttributes *imageAttributes = NULL)
+ {
+ GpTexture *texture = NULL;
+
+ lastResult = DllExports::GdipCreateTextureIAI(
+ image->nativeImage,
+ (imageAttributes)?imageAttributes->nativeImageAttr:NULL,
+ dstRect.X,
+ dstRect.Y,
+ dstRect.Width,
+ dstRect.Height,
+ &texture
+ );
+
+ SetNativeBrush(texture);
+ }
+ #endif
+
+ // When creating a texture brush from a metafile image, the dstRect
+ // is used to specify the size that the metafile image should be
+ // rendered at in the device units of the destination graphics.
+ // It is NOT used to crop the metafile image, so only the width
+ // and height values matter for metafiles.
+
+ TextureBrush(
+ IN Image* image,
+ IN WrapMode wrapMode,
+
+ #ifdef DCR_USE_NEW_145138
+ const IN Rect &dstRect
+ #else
+ IN Rect &dstRect
+ #endif
+ )
+ {
+ GpTexture *texture = NULL;
+
+ lastResult = DllExports::GdipCreateTexture2I(
+ image->nativeImage,
+ wrapMode,
+ dstRect.X,
+ dstRect.Y,
+ dstRect.Width,
+ dstRect.Height,
+ &texture);
+
+ SetNativeBrush(texture);
+ }
+
+ // When creating a texture brush from a metafile image, the dstRect
+ // is used to specify the size that the metafile image should be
+ // rendered at in the device units of the destination graphics.
+ // It is NOT used to crop the metafile image, so only the width
+ // and height values matter for metafiles.
+ TextureBrush(IN Image* image,
+ IN WrapMode wrapMode,
+ IN REAL dstX,
+ IN REAL dstY,
+ IN REAL dstWidth,
+ IN REAL dstHeight)
+ {
+ GpTexture *texture = NULL;
+
+ lastResult = DllExports::GdipCreateTexture2(
+ image->nativeImage,
+ wrapMode,
+ dstX,
+ dstY,
+ dstWidth,
+ dstHeight,
+ &texture);
+
+ SetNativeBrush(texture);
+ }
+
+ // When creating a texture brush from a metafile image, the dstRect
+ // is used to specify the size that the metafile image should be
+ // rendered at in the device units of the destination graphics.
+ // It is NOT used to crop the metafile image, so only the width
+ // and height values matter for metafiles.
+ TextureBrush(IN Image* image,
+ IN WrapMode wrapMode,
+ IN INT dstX,
+ IN INT dstY,
+ IN INT dstWidth,
+ IN INT dstHeight)
+ {
+ GpTexture *texture = NULL;
+
+ lastResult = DllExports::GdipCreateTexture2I(
+ image->nativeImage,
+ wrapMode,
+ dstX,
+ dstY,
+ dstWidth,
+ dstHeight,
+ &texture);
+
+ SetNativeBrush(texture);
+ }
+
+ /**
+ * Set/get brush transform
+ */
+ Status SetTransform(IN const Matrix* matrix)
+ {
+ return SetStatus(DllExports::GdipSetTextureTransform((GpTexture*)nativeBrush,
+ matrix->nativeMatrix));
+ }
+
+ Status GetTransform(OUT Matrix* matrix) const
+ {
+ return SetStatus(DllExports::GdipGetTextureTransform((GpTexture*)nativeBrush,
+ matrix->nativeMatrix));
+ }
+
+ Status ResetTransform()
+ {
+ return SetStatus(DllExports::GdipResetTextureTransform((GpTexture*)nativeBrush));
+ }
+
+ Status MultiplyTransform(IN const Matrix* matrix,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipMultiplyTextureTransform((GpTexture*)nativeBrush,
+ matrix->nativeMatrix,
+ order));
+ }
+
+ Status TranslateTransform(IN REAL dx,
+ IN REAL dy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipTranslateTextureTransform((GpTexture*)nativeBrush,
+ dx, dy, order));
+ }
+
+ Status ScaleTransform(IN REAL sx,
+ IN REAL sy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipScaleTextureTransform((GpTexture*)nativeBrush,
+ sx, sy, order));
+ }
+
+ Status RotateTransform(IN REAL angle,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipRotateTextureTransform((GpTexture*)nativeBrush,
+ angle, order));
+ }
+
+ /**
+ * Set/get brush wrapping mode
+ */
+ Status SetWrapMode(IN WrapMode wrapMode)
+ {
+ return SetStatus(DllExports::GdipSetTextureWrapMode((GpTexture*)nativeBrush,
+ wrapMode));
+ }
+
+ WrapMode GetWrapMode() const
+ {
+ WrapMode wrapMode;
+
+ SetStatus(DllExports::GdipGetTextureWrapMode((GpTexture*)nativeBrush,
+ &wrapMode));
+ return wrapMode;
+ }
+
+ // Get texture brush attributes
+
+ Image *GetImage() const
+ {
+ GpImage *image;
+
+ SetStatus(DllExports::GdipGetTextureImage((GpTexture *)nativeBrush,
+ &image));
+
+ Image *retimage = new Image(image, lastResult);
+
+ if (retimage == NULL)
+ {
+ DllExports::GdipDisposeImage(image);
+ }
+
+ return retimage;
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ TextureBrush(const TextureBrush &);
+ TextureBrush& operator=(const TextureBrush &);
+
+#endif
+
+protected:
+
+ TextureBrush()
+ {
+ }
+};
+
+//--------------------------------------------------------------------------
+// Represent line gradient brush object
+//--------------------------------------------------------------------------
+
+class LinearGradientBrush : public Brush
+{
+public:
+ friend class Pen;
+
+ LinearGradientBrush(IN const PointF& point1,
+ IN const PointF& point2,
+ IN const Color& color1,
+ IN const Color& color2)
+ {
+ GpLineGradient *brush = NULL;
+
+ lastResult = DllExports::GdipCreateLineBrush(&point1,
+ &point2,
+ color1.GetValue(),
+ color2.GetValue(),
+ WrapModeTile,
+ &brush);
+
+ SetNativeBrush(brush);
+ }
+
+ LinearGradientBrush(IN const Point& point1,
+ IN const Point& point2,
+ IN const Color& color1,
+ IN const Color& color2)
+ {
+ GpLineGradient *brush = NULL;
+
+ lastResult = DllExports::GdipCreateLineBrushI(&point1,
+ &point2,
+ color1.GetValue(),
+ color2.GetValue(),
+ WrapModeTile,
+ &brush);
+
+ SetNativeBrush(brush);
+ }
+
+ LinearGradientBrush(IN const RectF& rect,
+ IN const Color& color1,
+ IN const Color& color2,
+ IN LinearGradientMode mode)
+ {
+ GpLineGradient *brush = NULL;
+
+ lastResult = DllExports::GdipCreateLineBrushFromRect(&rect,
+ color1.GetValue(),
+ color2.GetValue(),
+ mode,
+ WrapModeTile,
+ &brush);
+
+ SetNativeBrush(brush);
+ }
+
+ LinearGradientBrush(IN const Rect& rect,
+ IN const Color& color1,
+ IN const Color& color2,
+ IN LinearGradientMode mode)
+ {
+ GpLineGradient *brush = NULL;
+
+ lastResult = DllExports::GdipCreateLineBrushFromRectI(&rect,
+ color1.GetValue(),
+ color2.GetValue(),
+ mode,
+ WrapModeTile,
+ &brush);
+
+ SetNativeBrush(brush);
+ }
+
+ LinearGradientBrush(IN const RectF& rect,
+ IN const Color& color1,
+ IN const Color& color2,
+ IN REAL angle,
+ IN BOOL isAngleScalable = FALSE)
+ {
+ GpLineGradient *brush = NULL;
+
+ lastResult = DllExports::GdipCreateLineBrushFromRectWithAngle(&rect,
+ color1.GetValue(),
+ color2.GetValue(),
+ angle,
+ isAngleScalable,
+ WrapModeTile,
+ &brush);
+
+ SetNativeBrush(brush);
+ }
+
+ LinearGradientBrush(IN const Rect& rect,
+ IN const Color& color1,
+ IN const Color& color2,
+ IN REAL angle,
+ IN BOOL isAngleScalable = FALSE)
+ {
+ GpLineGradient *brush = NULL;
+
+ lastResult = DllExports::GdipCreateLineBrushFromRectWithAngleI(&rect,
+ color1.GetValue(),
+ color2.GetValue(),
+ angle,
+ isAngleScalable,
+ WrapModeTile,
+ &brush);
+
+ SetNativeBrush(brush);
+ }
+
+ // Get/set point attributes
+
+ Status SetLinearPoints(IN const PointF& point1,
+ IN const PointF& point2)
+ {
+ return SetStatus(DllExports::GdipSetLinePoints((GpLineGradient*)nativeBrush,
+ &point1, &point2));
+ }
+
+ Status GetLinearPoints(OUT PointF* points) const
+ {
+ return SetStatus(DllExports::GdipGetLinePoints((GpLineGradient*) nativeBrush,
+ points));
+ }
+
+ Status SetLinearPoints(IN const Point& point1,
+ IN const Point& point2)
+ {
+ return SetStatus(DllExports::GdipSetLinePointsI((GpLineGradient*)nativeBrush,
+ &point1, &point2));
+ }
+
+ Status GetLinearPoints(OUT Point* points) const
+ {
+ return SetStatus(DllExports::GdipGetLinePointsI((GpLineGradient*) nativeBrush,
+ points));
+ }
+ // Get/set color attributes
+
+ Status SetLinearColors(IN const Color& color1,
+ IN const Color& color2)
+ {
+ return SetStatus(DllExports::GdipSetLineColors((GpLineGradient*)nativeBrush,
+ color1.GetValue(),
+ color2.GetValue()));
+ }
+
+ Status GetLinearColors(OUT Color* colors) const
+ {
+ ARGB argb[2];
+
+ if (colors == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ SetStatus(DllExports::GdipGetLineColors((GpLineGradient*) nativeBrush, argb));
+
+ if (lastResult == Ok)
+ {
+ // use bitwise copy operator for Color copy
+ colors[0] = Color(argb[0]);
+ colors[1] = Color(argb[1]);
+ }
+
+ return lastResult;
+ }
+
+ Status GetRectangle(OUT RectF* rect) const
+ {
+ return SetStatus(DllExports::GdipGetLineRect((GpLineGradient*)nativeBrush, rect));
+ }
+
+ // integer version
+ Status GetRectangle(OUT Rect* rect) const
+ {
+ return SetStatus(DllExports::GdipGetLineRectI((GpLineGradient*)nativeBrush, rect));
+ }
+
+ // Gamma correction in interporlation.
+
+ Status SetGammaCorrection(IN BOOL useGammaCorrection)
+ {
+ return SetStatus(DllExports::GdipSetLineGammaCorrection((GpLineGradient*)nativeBrush,
+ useGammaCorrection));
+ }
+
+ BOOL GetGammaCorrection() const
+ {
+ BOOL useGammaCorrection;
+
+ SetStatus(DllExports::GdipGetLineGammaCorrection((GpLineGradient*)nativeBrush,
+ &useGammaCorrection));
+
+ return useGammaCorrection;
+ }
+
+ INT GetBlendCount() const
+ {
+ INT count = 0;
+
+ SetStatus(DllExports::GdipGetLineBlendCount((GpLineGradient*)
+ nativeBrush,
+ &count));
+
+ return count;
+ }
+
+ Status SetBlend(IN const REAL* blendFactors,
+ IN const REAL* blendPositions,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipSetLineBlend((GpLineGradient*)
+ nativeBrush,
+ blendFactors,
+ blendPositions,
+ count));
+ }
+
+ Status GetBlend(OUT REAL* blendFactors,
+ OUT REAL* blendPositions,
+ IN INT count) const
+ {
+ return SetStatus(DllExports::GdipGetLineBlend((GpLineGradient*)nativeBrush,
+ blendFactors,
+ blendPositions,
+ count));
+ }
+
+ INT GetInterpolationColorCount() const
+ {
+ INT count = 0;
+
+ SetStatus(DllExports::GdipGetLinePresetBlendCount((GpLineGradient*)
+ nativeBrush,
+ &count));
+
+ return count;
+ }
+
+ Status SetInterpolationColors(IN const Color* presetColors,
+ IN const REAL* blendPositions,
+ IN INT count)
+ {
+ if ((count <= 0) || !presetColors)
+ return SetStatus(InvalidParameter);
+
+ ARGB *argbs = (ARGB*) new BYTE[count*sizeof(ARGB)];
+
+ if (argbs)
+ {
+ for (INT i = 0; i < count; i++)
+ {
+ argbs[i] = presetColors[i].GetValue();
+ }
+
+ Status status = SetStatus(DllExports::GdipSetLinePresetBlend(
+ (GpLineGradient*) nativeBrush,
+ argbs,
+ blendPositions,
+ count));
+ delete [] argbs;
+ return status;
+ }
+ else
+ {
+ return SetStatus(OutOfMemory);
+ }
+ }
+
+ Status GetInterpolationColors(OUT Color* presetColors,
+ OUT REAL* blendPositions,
+ IN INT count) const
+ {
+ if ((count <= 0) || !presetColors)
+ return SetStatus(InvalidParameter);
+
+ ARGB* argbs = (ARGB*) new BYTE[count*sizeof(ARGB)];
+
+ if (!argbs)
+ {
+ return SetStatus(OutOfMemory);
+ }
+
+ Status status = SetStatus(DllExports::GdipGetLinePresetBlend((GpLineGradient*)nativeBrush,
+ argbs,
+ blendPositions,
+ count));
+ if (status == Ok)
+ {
+ for (INT i = 0; i < count; i++)
+ {
+ presetColors[i] = Color(argbs[i]);
+ }
+ }
+
+ delete [] argbs;
+
+ return status;
+ }
+
+ Status SetBlendBellShape(IN REAL focus,
+ IN REAL scale = 1.0)
+ {
+ return SetStatus(DllExports::GdipSetLineSigmaBlend((GpLineGradient*)nativeBrush, focus, scale));
+ }
+
+ #ifdef DCR_USE_NEW_145135
+ Status SetBlendTriangularShape(
+ IN REAL focus,
+ IN REAL scale = 1.0
+ )
+ #else
+ Status SetBlendTrianglarShape(IN REAL focus,
+ IN REAL scale = 1.0)
+ #endif
+ {
+ return SetStatus(DllExports::GdipSetLineLinearBlend((GpLineGradient*)nativeBrush, focus, scale));
+ }
+
+ /**
+ * Set/get brush transform
+ */
+ Status SetTransform(IN const Matrix* matrix)
+ {
+ return SetStatus(DllExports::GdipSetLineTransform((GpLineGradient*)nativeBrush,
+ matrix->nativeMatrix));
+ }
+
+ Status GetTransform(OUT Matrix *matrix) const
+ {
+ return SetStatus(DllExports::GdipGetLineTransform((GpLineGradient*)nativeBrush,
+ matrix->nativeMatrix));
+ }
+
+ Status ResetTransform()
+ {
+ return SetStatus(DllExports::GdipResetLineTransform((GpLineGradient*)nativeBrush));
+ }
+
+ Status MultiplyTransform(IN const Matrix* matrix,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipMultiplyLineTransform((GpLineGradient*)nativeBrush,
+ matrix->nativeMatrix,
+ order));
+ }
+
+ Status TranslateTransform(IN REAL dx,
+ IN REAL dy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipTranslateLineTransform((GpLineGradient*)nativeBrush,
+ dx, dy, order));
+ }
+
+ Status ScaleTransform(IN REAL sx,
+ IN REAL sy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipScaleLineTransform((GpLineGradient*)nativeBrush,
+ sx, sy, order));
+ }
+
+ Status RotateTransform(IN REAL angle,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipRotateLineTransform((GpLineGradient*)nativeBrush,
+ angle, order));
+ }
+
+ /**
+ * Set/get brush wrapping mode
+ */
+ Status SetWrapMode(IN WrapMode wrapMode)
+ {
+ return SetStatus(DllExports::GdipSetLineWrapMode((GpLineGradient*)nativeBrush,
+ wrapMode));
+ }
+
+ WrapMode GetWrapMode() const
+ {
+ WrapMode wrapMode;
+
+ SetStatus(DllExports::GdipGetLineWrapMode((GpLineGradient*)
+ nativeBrush,
+ &wrapMode));
+
+ return wrapMode;
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ LinearGradientBrush(const LinearGradientBrush &);
+ LinearGradientBrush& operator=(const LinearGradientBrush &);
+
+#endif
+
+protected:
+
+ LinearGradientBrush()
+ {
+ }
+};
+
+//--------------------------------------------------------------------------
+// PathGradientBrush object is defined
+// in gdipluspath.h.
+//--------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+// Represent hatch brush object
+//--------------------------------------------------------------------------
+
+class HatchBrush : public Brush
+{
+public:
+ friend class Pen;
+
+ // Constructors
+
+ HatchBrush(IN HatchStyle hatchStyle,
+ IN const Color& foreColor,
+ IN const Color& backColor = Color())
+ {
+ GpHatch *brush = NULL;
+
+ lastResult = DllExports::GdipCreateHatchBrush(hatchStyle,
+ foreColor.GetValue(),
+ backColor.GetValue(),
+ &brush);
+ SetNativeBrush(brush);
+ }
+
+ HatchStyle GetHatchStyle() const
+ {
+ HatchStyle hatchStyle;
+
+ SetStatus(DllExports::GdipGetHatchStyle((GpHatch*)nativeBrush,
+ &hatchStyle));
+
+ return hatchStyle;
+ }
+
+ Status GetForegroundColor(OUT Color* color) const
+ {
+ ARGB argb;
+
+ if (color == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ Status status = SetStatus(DllExports::GdipGetHatchForegroundColor(
+ (GpHatch*)nativeBrush,
+ &argb));
+
+ color->SetValue(argb);
+
+ return status;
+ }
+
+ Status GetBackgroundColor(OUT Color *color) const
+ {
+ ARGB argb;
+
+ if (color == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ Status status = SetStatus(DllExports::GdipGetHatchBackgroundColor(
+ (GpHatch*)nativeBrush,
+ &argb));
+
+ color->SetValue(argb);
+
+ return status;
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ HatchBrush(const HatchBrush &);
+ HatchBrush& operator=(const HatchBrush &);
+
+#endif
+
+protected:
+
+ HatchBrush()
+ {
+ }
+};
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusCachedBitmap.h b/core/src/fxge/Microsoft SDK/include/GdiPlusCachedBitmap.h
index 28fd8caea6..3bafebeb40 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusCachedBitmap.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusCachedBitmap.h
@@ -1,71 +1,71 @@
-/**************************************************************************
-*
-* Copyright (c) 2000 Microsoft Corporation
-*
-* Module Name:
-*
-* CachedBitmap class definition
-*
-* Abstract:
-*
-* CachedBitmap is a representation of an accelerated drawing
-* that has restrictions on what operations are allowed in order
-* to accelerate the drawing to the destination.
-*
-**************************************************************************/
-
-#ifndef _GDIPLUSCACHEDBITMAP_H
-#define _GDIPLUSCACHEDBITMAP_H
-
-/**************************************************************************
-*
-* Class Name:
-*
-* CachedBitmap
-*
-* Abstract:
-*
-* An object to store a bitmap prepared for rendering on a particular
-* Graphics object. The memory storage for the CachedBitmap is opaque
-* to the other Engine code, so the only operations supported are
-* initializing the data (with a bitmap) and using the graphics to
-* draw it on the screen with an integer offset.
-*
-* Look for the class definition in GdiplusHeaders.h
-*
-* Created:
-*
-* 04/23/2000 asecchia
-* Created it.
-*
-**************************************************************************/
-inline
-CachedBitmap::CachedBitmap(
- IN Bitmap *bitmap,
- IN Graphics *graphics)
-{
- nativeCachedBitmap = NULL;
-
- lastResult = DllExports::GdipCreateCachedBitmap(
- (GpBitmap *)bitmap->nativeImage,
- graphics->nativeGraphics,
- &nativeCachedBitmap
- );
-}
-
-inline
-CachedBitmap::~CachedBitmap()
-{
- DllExports::GdipDeleteCachedBitmap(nativeCachedBitmap);
-}
-
-inline Status
-CachedBitmap::GetLastStatus() const
-{
- Status lastStatus = lastResult;
- lastResult = Ok;
- return (lastStatus);
-}
-
-#endif
-
+/**************************************************************************
+*
+* Copyright (c) 2000 Microsoft Corporation
+*
+* Module Name:
+*
+* CachedBitmap class definition
+*
+* Abstract:
+*
+* CachedBitmap is a representation of an accelerated drawing
+* that has restrictions on what operations are allowed in order
+* to accelerate the drawing to the destination.
+*
+**************************************************************************/
+
+#ifndef _GDIPLUSCACHEDBITMAP_H
+#define _GDIPLUSCACHEDBITMAP_H
+
+/**************************************************************************
+*
+* Class Name:
+*
+* CachedBitmap
+*
+* Abstract:
+*
+* An object to store a bitmap prepared for rendering on a particular
+* Graphics object. The memory storage for the CachedBitmap is opaque
+* to the other Engine code, so the only operations supported are
+* initializing the data (with a bitmap) and using the graphics to
+* draw it on the screen with an integer offset.
+*
+* Look for the class definition in GdiplusHeaders.h
+*
+* Created:
+*
+* 04/23/2000 asecchia
+* Created it.
+*
+**************************************************************************/
+inline
+CachedBitmap::CachedBitmap(
+ IN Bitmap *bitmap,
+ IN Graphics *graphics)
+{
+ nativeCachedBitmap = NULL;
+
+ lastResult = DllExports::GdipCreateCachedBitmap(
+ (GpBitmap *)bitmap->nativeImage,
+ graphics->nativeGraphics,
+ &nativeCachedBitmap
+ );
+}
+
+inline
+CachedBitmap::~CachedBitmap()
+{
+ DllExports::GdipDeleteCachedBitmap(nativeCachedBitmap);
+}
+
+inline Status
+CachedBitmap::GetLastStatus() const
+{
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+ return (lastStatus);
+}
+
+#endif
+
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusColor.h b/core/src/fxge/Microsoft SDK/include/GdiPlusColor.h
index 72c21c295f..7ec10f8434 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusColor.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusColor.h
@@ -1,209 +1,209 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusColor.h
-*
-* Abstract:
-*
-* Represents a GDI+ color.
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSCOLOR_H
-#define _GDIPLUSCOLOR_H
-
-//----------------------------------------------------------------------------
-// Color mode
-//----------------------------------------------------------------------------
-
-enum ColorMode
-{
- ColorModeARGB32 = 0,
- ColorModeARGB64 = 1
-};
-
-//----------------------------------------------------------------------------
-// Color Channel flags
-//----------------------------------------------------------------------------
-
-enum ColorChannelFlags
-{
- ColorChannelFlagsC = 0,
- ColorChannelFlagsM,
- ColorChannelFlagsY,
- ColorChannelFlagsK,
- ColorChannelFlagsLast
-};
-
-//----------------------------------------------------------------------------
-// Color
-//----------------------------------------------------------------------------
-
-class Color
-{
-public:
-
- Color()
- {
- Argb = (ARGB)Color::Black;
- }
-
- // Construct an opaque Color object with
- // the specified R, G, B values.
-
- Color(IN BYTE r,
- IN BYTE g,
- IN BYTE b)
- {
- Argb = MakeARGB(255, r, g, b);
- }
-
- // Construct a Color object with
- // the specified A, R, G, B values.
- //
- // NOTE: R, G, B color values are not premultiplied.
-
- Color(IN BYTE a,
- IN BYTE r,
- IN BYTE g,
- IN BYTE b)
- {
- Argb = MakeARGB(a, r, g, b);
- }
-
- // Construct a Color object with
- // the specified ARGB values.
- //
- // NOTE: R, G, B color components are not premultiplied.
-
- Color(IN ARGB argb)
- {
- Argb = argb;
- }
-
- // Extract A, R, G, B components
-
- BYTE GetAlpha() const
- {
- return (BYTE) (Argb >> AlphaShift);
- }
-
- BYTE GetA() const
- {
- return GetAlpha();
- }
-
- BYTE GetRed() const
- {
- return (BYTE) (Argb >> RedShift);
- }
-
- BYTE GetR() const
- {
- return GetRed();
- }
-
- BYTE GetGreen() const
- {
- return (BYTE) (Argb >> GreenShift);
- }
-
- BYTE GetG() const
- {
- return GetGreen();
- }
-
- BYTE GetBlue() const
- {
- return (BYTE) (Argb >> BlueShift);
- }
-
- BYTE GetB() const
- {
- return GetBlue();
- }
-
- // Retrieve ARGB values
-
- ARGB GetValue() const
- {
- return Argb;
- }
-
- VOID SetValue(IN ARGB argb)
- {
- Argb = argb;
- }
-
- VOID SetFromCOLORREF(IN COLORREF rgb)
- {
- Argb = MakeARGB(255, GetRValue(rgb), GetGValue(rgb), GetBValue(rgb));
- }
-
- COLORREF ToCOLORREF() const
- {
- return RGB(GetRed(), GetGreen(), GetBlue());
- }
-
-public:
-
- // Standard color constants
- enum
- {
- Black = 0xff000000,
- Silver = 0xffc0c0c0,
- Gray = 0xff808080,
- White = 0xffffffff,
- Maroon = 0xff800000,
- Red = 0xffff0000,
- Purple = 0xff800080,
- Fuchsia = 0xffff00ff,
- Green = 0xff008000,
- Lime = 0xff00ff00,
- Olive = 0xff808000,
- Yellow = 0xffffff00,
- Navy = 0xff000080,
- Blue = 0xff0000ff,
- Teal = 0xff008080,
- Aqua = 0xff00ffff
- };
-
- // Shift count and bit mask for A, R, G, B components
- enum
- {
- AlphaShift = 24,
- RedShift = 16,
- GreenShift = 8,
- BlueShift = 0
- };
-
- enum
- {
- AlphaMask = 0xff000000,
- RedMask = 0x00ff0000,
- GreenMask = 0x0000ff00,
- BlueMask = 0x000000ff
- };
-
- // Assemble A, R, G, B values into a 32-bit integer
- static ARGB MakeARGB(IN BYTE a,
- IN BYTE r,
- IN BYTE g,
- IN BYTE b)
- {
- return (((ARGB) (b) << BlueShift) |
- ((ARGB) (g) << GreenShift) |
- ((ARGB) (r) << RedShift) |
- ((ARGB) (a) << AlphaShift));
- }
-
-protected:
-
- ARGB Argb;
-};
-
-#endif
-
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusColor.h
+*
+* Abstract:
+*
+* Represents a GDI+ color.
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSCOLOR_H
+#define _GDIPLUSCOLOR_H
+
+//----------------------------------------------------------------------------
+// Color mode
+//----------------------------------------------------------------------------
+
+enum ColorMode
+{
+ ColorModeARGB32 = 0,
+ ColorModeARGB64 = 1
+};
+
+//----------------------------------------------------------------------------
+// Color Channel flags
+//----------------------------------------------------------------------------
+
+enum ColorChannelFlags
+{
+ ColorChannelFlagsC = 0,
+ ColorChannelFlagsM,
+ ColorChannelFlagsY,
+ ColorChannelFlagsK,
+ ColorChannelFlagsLast
+};
+
+//----------------------------------------------------------------------------
+// Color
+//----------------------------------------------------------------------------
+
+class Color
+{
+public:
+
+ Color()
+ {
+ Argb = (ARGB)Color::Black;
+ }
+
+ // Construct an opaque Color object with
+ // the specified R, G, B values.
+
+ Color(IN BYTE r,
+ IN BYTE g,
+ IN BYTE b)
+ {
+ Argb = MakeARGB(255, r, g, b);
+ }
+
+ // Construct a Color object with
+ // the specified A, R, G, B values.
+ //
+ // NOTE: R, G, B color values are not premultiplied.
+
+ Color(IN BYTE a,
+ IN BYTE r,
+ IN BYTE g,
+ IN BYTE b)
+ {
+ Argb = MakeARGB(a, r, g, b);
+ }
+
+ // Construct a Color object with
+ // the specified ARGB values.
+ //
+ // NOTE: R, G, B color components are not premultiplied.
+
+ Color(IN ARGB argb)
+ {
+ Argb = argb;
+ }
+
+ // Extract A, R, G, B components
+
+ BYTE GetAlpha() const
+ {
+ return (BYTE) (Argb >> AlphaShift);
+ }
+
+ BYTE GetA() const
+ {
+ return GetAlpha();
+ }
+
+ BYTE GetRed() const
+ {
+ return (BYTE) (Argb >> RedShift);
+ }
+
+ BYTE GetR() const
+ {
+ return GetRed();
+ }
+
+ BYTE GetGreen() const
+ {
+ return (BYTE) (Argb >> GreenShift);
+ }
+
+ BYTE GetG() const
+ {
+ return GetGreen();
+ }
+
+ BYTE GetBlue() const
+ {
+ return (BYTE) (Argb >> BlueShift);
+ }
+
+ BYTE GetB() const
+ {
+ return GetBlue();
+ }
+
+ // Retrieve ARGB values
+
+ ARGB GetValue() const
+ {
+ return Argb;
+ }
+
+ VOID SetValue(IN ARGB argb)
+ {
+ Argb = argb;
+ }
+
+ VOID SetFromCOLORREF(IN COLORREF rgb)
+ {
+ Argb = MakeARGB(255, GetRValue(rgb), GetGValue(rgb), GetBValue(rgb));
+ }
+
+ COLORREF ToCOLORREF() const
+ {
+ return RGB(GetRed(), GetGreen(), GetBlue());
+ }
+
+public:
+
+ // Standard color constants
+ enum
+ {
+ Black = 0xff000000,
+ Silver = 0xffc0c0c0,
+ Gray = 0xff808080,
+ White = 0xffffffff,
+ Maroon = 0xff800000,
+ Red = 0xffff0000,
+ Purple = 0xff800080,
+ Fuchsia = 0xffff00ff,
+ Green = 0xff008000,
+ Lime = 0xff00ff00,
+ Olive = 0xff808000,
+ Yellow = 0xffffff00,
+ Navy = 0xff000080,
+ Blue = 0xff0000ff,
+ Teal = 0xff008080,
+ Aqua = 0xff00ffff
+ };
+
+ // Shift count and bit mask for A, R, G, B components
+ enum
+ {
+ AlphaShift = 24,
+ RedShift = 16,
+ GreenShift = 8,
+ BlueShift = 0
+ };
+
+ enum
+ {
+ AlphaMask = 0xff000000,
+ RedMask = 0x00ff0000,
+ GreenMask = 0x0000ff00,
+ BlueMask = 0x000000ff
+ };
+
+ // Assemble A, R, G, B values into a 32-bit integer
+ static ARGB MakeARGB(IN BYTE a,
+ IN BYTE r,
+ IN BYTE g,
+ IN BYTE b)
+ {
+ return (((ARGB) (b) << BlueShift) |
+ ((ARGB) (g) << GreenShift) |
+ ((ARGB) (r) << RedShift) |
+ ((ARGB) (a) << AlphaShift));
+ }
+
+protected:
+
+ ARGB Argb;
+};
+
+#endif
+
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusColorMatrix.h b/core/src/fxge/Microsoft SDK/include/GdiPlusColorMatrix.h
index d1d9ebc534..ec4d14b191 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusColorMatrix.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusColorMatrix.h
@@ -1,63 +1,63 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusColorMatrix.h
-*
-* Abstract:
-*
-* Class for color adjustment object passed to Graphics.DrawImage
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSCOLORMATRIX_H
-#define _GDIPLUSCOLORMATRIX_H
-
-//----------------------------------------------------------------------------
-// Color matrix
-//----------------------------------------------------------------------------
-
-struct ColorMatrix
-{
- REAL m[5][5];
-};
-
-//----------------------------------------------------------------------------
-// Color Matrix flags
-//----------------------------------------------------------------------------
-
-enum ColorMatrixFlags
-{
- ColorMatrixFlagsDefault = 0,
- ColorMatrixFlagsSkipGrays = 1,
- ColorMatrixFlagsAltGray = 2
-};
-
-//----------------------------------------------------------------------------
-// Color Adjust Type
-//----------------------------------------------------------------------------
-
-enum ColorAdjustType
-{
- ColorAdjustTypeDefault,
- ColorAdjustTypeBitmap,
- ColorAdjustTypeBrush,
- ColorAdjustTypePen,
- ColorAdjustTypeText,
- ColorAdjustTypeCount, // must be immediately after all the individual ones
- ColorAdjustTypeAny // internal use: for querying if any type has recoloring
-};
-
-//----------------------------------------------------------------------------
-// Color Map
-//----------------------------------------------------------------------------
-
-struct ColorMap
-{
- Color oldColor;
- Color newColor;
-};
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusColorMatrix.h
+*
+* Abstract:
+*
+* Class for color adjustment object passed to Graphics.DrawImage
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSCOLORMATRIX_H
+#define _GDIPLUSCOLORMATRIX_H
+
+//----------------------------------------------------------------------------
+// Color matrix
+//----------------------------------------------------------------------------
+
+struct ColorMatrix
+{
+ REAL m[5][5];
+};
+
+//----------------------------------------------------------------------------
+// Color Matrix flags
+//----------------------------------------------------------------------------
+
+enum ColorMatrixFlags
+{
+ ColorMatrixFlagsDefault = 0,
+ ColorMatrixFlagsSkipGrays = 1,
+ ColorMatrixFlagsAltGray = 2
+};
+
+//----------------------------------------------------------------------------
+// Color Adjust Type
+//----------------------------------------------------------------------------
+
+enum ColorAdjustType
+{
+ ColorAdjustTypeDefault,
+ ColorAdjustTypeBitmap,
+ ColorAdjustTypeBrush,
+ ColorAdjustTypePen,
+ ColorAdjustTypeText,
+ ColorAdjustTypeCount, // must be immediately after all the individual ones
+ ColorAdjustTypeAny // internal use: for querying if any type has recoloring
+};
+
+//----------------------------------------------------------------------------
+// Color Map
+//----------------------------------------------------------------------------
+
+struct ColorMap
+{
+ Color oldColor;
+ Color newColor;
+};
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusEnums.h b/core/src/fxge/Microsoft SDK/include/GdiPlusEnums.h
index 92a29c7463..9962ff586a 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusEnums.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusEnums.h
@@ -1,1252 +1,1252 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusEnums.h
-*
-* Abstract:
-*
-* Various enumeration types
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSENUMS_H
-#define _GDIPLUSENUMS_H
-
-
-//--------------------------------------------------------------------------
-// Default bezier flattening tolerance in device pixels.
-//--------------------------------------------------------------------------
-
-const float FlatnessDefault = 1.0f/4.0f;
-
-//--------------------------------------------------------------------------
-// Graphics and Container State cookies
-//--------------------------------------------------------------------------
-
-typedef UINT GraphicsState;
-typedef UINT GraphicsContainer;
-
-//--------------------------------------------------------------------------
-// Fill mode constants
-//--------------------------------------------------------------------------
-
-enum FillMode
-{
- FillModeAlternate, // 0
- FillModeWinding // 1
-};
-
-//--------------------------------------------------------------------------
-// Quality mode constants
-//--------------------------------------------------------------------------
-
-enum QualityMode
-{
- QualityModeInvalid = -1,
- QualityModeDefault = 0,
- QualityModeLow = 1, // for apps that need the best performance
- QualityModeHigh = 2 // for apps that need the best rendering quality
-};
-
-//--------------------------------------------------------------------------
-// Alpha compositing mode constants
-//--------------------------------------------------------------------------
-
-enum CompositingMode
-{
- CompositingModeSourceOver, // 0
- CompositingModeSourceCopy // 1
-};
-
-//--------------------------------------------------------------------------
-// Alpha compositing quality constants
-//--------------------------------------------------------------------------
-
-enum CompositingQuality
-{
- CompositingQualityInvalid = QualityModeInvalid,
- CompositingQualityDefault = QualityModeDefault,
- CompositingQualityHighSpeed = QualityModeLow,
- CompositingQualityHighQuality = QualityModeHigh,
- CompositingQualityGammaCorrected,
- CompositingQualityAssumeLinear
-};
-
-//--------------------------------------------------------------------------
-// Unit constants
-//--------------------------------------------------------------------------
-
-enum Unit
-{
- UnitWorld, // 0 -- World coordinate (non-physical unit)
- UnitDisplay, // 1 -- Variable -- for PageTransform only
- UnitPixel, // 2 -- Each unit is one device pixel.
- UnitPoint, // 3 -- Each unit is a printer's point, or 1/72 inch.
- UnitInch, // 4 -- Each unit is 1 inch.
- UnitDocument, // 5 -- Each unit is 1/300 inch.
- UnitMillimeter // 6 -- Each unit is 1 millimeter.
-};
-
-//--------------------------------------------------------------------------
-// MetafileFrameUnit
-//
-// The frameRect for creating a metafile can be specified in any of these
-// units. There is an extra frame unit value (MetafileFrameUnitGdi) so
-// that units can be supplied in the same units that GDI expects for
-// frame rects -- these units are in .01 (1/100ths) millimeter units
-// as defined by GDI.
-//--------------------------------------------------------------------------
-enum MetafileFrameUnit
-{
- MetafileFrameUnitPixel = UnitPixel,
- MetafileFrameUnitPoint = UnitPoint,
- MetafileFrameUnitInch = UnitInch,
- MetafileFrameUnitDocument = UnitDocument,
- MetafileFrameUnitMillimeter = UnitMillimeter,
- MetafileFrameUnitGdi // GDI compatible .01 MM units
-};
-
-//--------------------------------------------------------------------------
-// Coordinate space identifiers
-//--------------------------------------------------------------------------
-
-enum CoordinateSpace
-{
- CoordinateSpaceWorld, // 0
- CoordinateSpacePage, // 1
- CoordinateSpaceDevice // 2
-};
-
-//--------------------------------------------------------------------------
-// Various wrap modes for brushes
-//--------------------------------------------------------------------------
-
-enum WrapMode
-{
- WrapModeTile, // 0
- WrapModeTileFlipX, // 1
- WrapModeTileFlipY, // 2
- WrapModeTileFlipXY, // 3
- WrapModeClamp // 4
-};
-
-//--------------------------------------------------------------------------
-// Various hatch styles
-//--------------------------------------------------------------------------
-
-enum HatchStyle
-{
- HatchStyleHorizontal, // 0
- HatchStyleVertical, // 1
- HatchStyleForwardDiagonal, // 2
- HatchStyleBackwardDiagonal, // 3
- HatchStyleCross, // 4
- HatchStyleDiagonalCross, // 5
- HatchStyle05Percent, // 6
- HatchStyle10Percent, // 7
- HatchStyle20Percent, // 8
- HatchStyle25Percent, // 9
- HatchStyle30Percent, // 10
- HatchStyle40Percent, // 11
- HatchStyle50Percent, // 12
- HatchStyle60Percent, // 13
- HatchStyle70Percent, // 14
- HatchStyle75Percent, // 15
- HatchStyle80Percent, // 16
- HatchStyle90Percent, // 17
- HatchStyleLightDownwardDiagonal, // 18
- HatchStyleLightUpwardDiagonal, // 19
- HatchStyleDarkDownwardDiagonal, // 20
- HatchStyleDarkUpwardDiagonal, // 21
- HatchStyleWideDownwardDiagonal, // 22
- HatchStyleWideUpwardDiagonal, // 23
- HatchStyleLightVertical, // 24
- HatchStyleLightHorizontal, // 25
- HatchStyleNarrowVertical, // 26
- HatchStyleNarrowHorizontal, // 27
- HatchStyleDarkVertical, // 28
- HatchStyleDarkHorizontal, // 29
- HatchStyleDashedDownwardDiagonal, // 30
- HatchStyleDashedUpwardDiagonal, // 31
- HatchStyleDashedHorizontal, // 32
- HatchStyleDashedVertical, // 33
- HatchStyleSmallConfetti, // 34
- HatchStyleLargeConfetti, // 35
- HatchStyleZigZag, // 36
- HatchStyleWave, // 37
- HatchStyleDiagonalBrick, // 38
- HatchStyleHorizontalBrick, // 39
- HatchStyleWeave, // 40
- HatchStylePlaid, // 41
- HatchStyleDivot, // 42
- HatchStyleDottedGrid, // 43
- HatchStyleDottedDiamond, // 44
- HatchStyleShingle, // 45
- HatchStyleTrellis, // 46
- HatchStyleSphere, // 47
- HatchStyleSmallGrid, // 48
- HatchStyleSmallCheckerBoard, // 49
- HatchStyleLargeCheckerBoard, // 50
- HatchStyleOutlinedDiamond, // 51
- HatchStyleSolidDiamond, // 52
-
- HatchStyleTotal, // must be after all unique hatch styles
-
- HatchStyleLargeGrid = HatchStyleCross, // 4 an alias for the cross style
-
- HatchStyleMin = HatchStyleHorizontal,
- HatchStyleMax = HatchStyleTotal - 1,
-};
-
-//--------------------------------------------------------------------------
-// Dash style constants
-//--------------------------------------------------------------------------
-
-enum DashStyle
-{
- DashStyleSolid, // 0
- DashStyleDash, // 1
- DashStyleDot, // 2
- DashStyleDashDot, // 3
- DashStyleDashDotDot, // 4
- DashStyleCustom // 5
-};
-
-//--------------------------------------------------------------------------
-// Dash cap constants
-//--------------------------------------------------------------------------
-
-enum DashCap
-{
- DashCapFlat = 0,
- DashCapRound = 2,
- DashCapTriangle = 3
-};
-
-//--------------------------------------------------------------------------
-// Line cap constants (only the lowest 8 bits are used).
-//--------------------------------------------------------------------------
-
-enum LineCap
-{
- LineCapFlat = 0,
- LineCapSquare = 1,
- LineCapRound = 2,
- LineCapTriangle = 3,
-
- LineCapNoAnchor = 0x10, // corresponds to flat cap
- LineCapSquareAnchor = 0x11, // corresponds to square cap
- LineCapRoundAnchor = 0x12, // corresponds to round cap
- LineCapDiamondAnchor = 0x13, // corresponds to triangle cap
- LineCapArrowAnchor = 0x14, // no correspondence
-
- LineCapCustom = 0xff, // custom cap
-
- LineCapAnchorMask = 0xf0 // mask to check for anchor or not.
-};
-
-//--------------------------------------------------------------------------
-// Custom Line cap type constants
-//--------------------------------------------------------------------------
-
-enum CustomLineCapType
-{
- CustomLineCapTypeDefault = 0,
- CustomLineCapTypeAdjustableArrow = 1
-};
-
-//--------------------------------------------------------------------------
-// Line join constants
-//--------------------------------------------------------------------------
-
-enum LineJoin
-{
- LineJoinMiter = 0,
- LineJoinBevel = 1,
- LineJoinRound = 2,
- LineJoinMiterClipped = 3
-};
-
-//--------------------------------------------------------------------------
-// Path point types (only the lowest 8 bits are used.)
-// The lowest 3 bits are interpreted as point type
-// The higher 5 bits are reserved for flags.
-//--------------------------------------------------------------------------
-
-enum PathPointType
-{
- PathPointTypeStart = 0, // move
- PathPointTypeLine = 1, // line
- PathPointTypeBezier = 3, // default Beizer (= cubic Bezier)
- PathPointTypePathTypeMask = 0x07, // type mask (lowest 3 bits).
- PathPointTypeDashMode = 0x10, // currently in dash mode.
- PathPointTypePathMarker = 0x20, // a marker for the path.
- PathPointTypeCloseSubpath = 0x80, // closed flag
-
- // Path types used for advanced path.
-
- PathPointTypeBezier2 = 2, // quadratic Beizer
- PathPointTypeBezier3 = 3, // cubic Bezier
- PathPointTypeBezier4 = 4, // quartic (4th order) Beizer
- PathPointTypeBezier5 = 5, // quintic (5th order) Bezier
- PathPointTypeBezier6 = 6 // hexaic (6th order) Bezier
-};
-
-
-//--------------------------------------------------------------------------
-// WarpMode constants
-//--------------------------------------------------------------------------
-
-enum WarpMode
-{
- WarpModePerspective, // 0
- WarpModeBilinear // 1
-};
-
-//--------------------------------------------------------------------------
-// LineGradient Mode
-//--------------------------------------------------------------------------
-
-enum LinearGradientMode
-{
- LinearGradientModeHorizontal, // 0
- LinearGradientModeVertical, // 1
- LinearGradientModeForwardDiagonal, // 2
- LinearGradientModeBackwardDiagonal // 3
-};
-
-//--------------------------------------------------------------------------
-// Region Comine Modes
-//--------------------------------------------------------------------------
-
-enum CombineMode
-{
- CombineModeReplace, // 0
- CombineModeIntersect, // 1
- CombineModeUnion, // 2
- CombineModeXor, // 3
- CombineModeExclude, // 4
- CombineModeComplement // 5 (does exclude from)
-};
-
-//--------------------------------------------------------------------------
- // Image types
-//--------------------------------------------------------------------------
-
-enum ImageType
-{
- ImageTypeUnknown, // 0
- ImageTypeBitmap, // 1
- ImageTypeMetafile // 2
-};
-
-//--------------------------------------------------------------------------
-// Interpolation modes
-//--------------------------------------------------------------------------
-
-enum InterpolationMode
-{
- InterpolationModeInvalid = QualityModeInvalid,
- InterpolationModeDefault = QualityModeDefault,
- InterpolationModeLowQuality = QualityModeLow,
- InterpolationModeHighQuality = QualityModeHigh,
- InterpolationModeBilinear,
- InterpolationModeBicubic,
- InterpolationModeNearestNeighbor,
- InterpolationModeHighQualityBilinear,
- InterpolationModeHighQualityBicubic
-};
-
-//--------------------------------------------------------------------------
-// Pen types
-//--------------------------------------------------------------------------
-enum PenAlignment
-{
- PenAlignmentCenter = 0,
- PenAlignmentInset = 1,
- PenAlignmentOutset = 2,
- PenAlignmentLeft = 3,
- PenAlignmentRight = 4
-};
-
-//--------------------------------------------------------------------------
-// Brush types
-//--------------------------------------------------------------------------
-
-enum BrushType
-{
- BrushTypeSolidColor = 0,
- BrushTypeHatchFill = 1,
- BrushTypeTextureFill = 2,
- BrushTypePathGradient = 3,
- BrushTypeLinearGradient = 4
-};
-
-//--------------------------------------------------------------------------
-// Pen's Fill types
-//--------------------------------------------------------------------------
-
-enum PenType
-{
- PenTypeSolidColor = BrushTypeSolidColor,
- PenTypeHatchFill = BrushTypeHatchFill,
- PenTypeTextureFill = BrushTypeTextureFill,
- PenTypePathGradient = BrushTypePathGradient,
- PenTypeLinearGradient = BrushTypeLinearGradient,
- PenTypeUnknown = -1
-};
-
-//--------------------------------------------------------------------------
-// Matrix Order
-//--------------------------------------------------------------------------
-
-enum MatrixOrder
-{
- MatrixOrderPrepend = 0,
- MatrixOrderAppend = 1
-};
-
-//--------------------------------------------------------------------------
-// Generic font families
-//--------------------------------------------------------------------------
-
-enum GenericFontFamily
-{
- GenericFontFamilySerif,
- GenericFontFamilySansSerif,
- GenericFontFamilyMonospace
-
-};
-
-//--------------------------------------------------------------------------
-// FontStyle: face types and common styles
-//--------------------------------------------------------------------------
-
-// These should probably be flags
-
-// Must have:
-// Regular = 0
-// Bold = 1
-// Italic = 2
-// BoldItalic = 3
-
-enum FontStyle
-{
- FontStyleRegular = 0,
- FontStyleBold = 1,
- FontStyleItalic = 2,
- FontStyleBoldItalic = 3,
- FontStyleUnderline = 4,
- FontStyleStrikeout = 8
-};
-
-//---------------------------------------------------------------------------
-// Smoothing Mode
-//---------------------------------------------------------------------------
-
-enum SmoothingMode
-{
- SmoothingModeInvalid = QualityModeInvalid,
- SmoothingModeDefault = QualityModeDefault,
- SmoothingModeHighSpeed = QualityModeLow,
- SmoothingModeHighQuality = QualityModeHigh,
- SmoothingModeNone,
- SmoothingModeAntiAlias
-};
-
-//---------------------------------------------------------------------------
-// Pixel Format Mode
-//---------------------------------------------------------------------------
-
-enum PixelOffsetMode
-{
- PixelOffsetModeInvalid = QualityModeInvalid,
- PixelOffsetModeDefault = QualityModeDefault,
- PixelOffsetModeHighSpeed = QualityModeLow,
- PixelOffsetModeHighQuality = QualityModeHigh,
- PixelOffsetModeNone, // no pixel offset
- PixelOffsetModeHalf // offset by -0.5, -0.5 for fast anti-alias perf
-};
-
-//---------------------------------------------------------------------------
-// Text Rendering Hint
-//---------------------------------------------------------------------------
-
-enum TextRenderingHint
-{
-#ifdef DCR_USE_NEW_186764
- TextRenderingHintSystemDefault = 0, // Glyph with system default rendering hint
- TextRenderingHintSingleBitPerPixelGridFit, // Glyph bitmap with hinting
-#else
- TextRenderingHintSingleBitPerPixelGridFit = 0, // Glyph bitmap with hinting
-#endif // DCR_USE_NEW_186764
- TextRenderingHintSingleBitPerPixel, // Glyph bitmap without hinting
- TextRenderingHintAntiAliasGridFit, // Glyph anti-alias bitmap with hinting
- TextRenderingHintAntiAlias, // Glyph anti-alias bitmap without hinting
- TextRenderingHintClearTypeGridFit // Glyph CT bitmap with hinting
-};
-
-//---------------------------------------------------------------------------
-// Metafile Types
-//---------------------------------------------------------------------------
-enum MetafileType
-{
- MetafileTypeInvalid, // Invalid metafile
- MetafileTypeWmf, // Standard WMF
- MetafileTypeWmfAldus, // Aldus Placeable Metafile format
- MetafileTypeEmf, // EMF (not EMF+)
- MetafileTypeEmfPlusOnly, // EMF+ without dual, down-level records
- MetafileTypeEmfPlusDual // EMF+ with dual, down-level records
-};
-
-// Specifies the type of EMF to record
-enum EmfType
-{
- EmfTypeEmfOnly = MetafileTypeEmf, // no EMF+, only EMF
- EmfTypeEmfPlusOnly = MetafileTypeEmfPlusOnly, // no EMF, only EMF+
- EmfTypeEmfPlusDual = MetafileTypeEmfPlusDual // both EMF+ and EMF
-};
-
-// All persistent objects must have a type listed here
-enum ObjectType
-{
- ObjectTypeInvalid,
- ObjectTypeBrush,
- ObjectTypePen,
- ObjectTypePath,
- ObjectTypeRegion,
- ObjectTypeImage,
- ObjectTypeFont,
- ObjectTypeStringFormat,
- ObjectTypeImageAttributes,
- ObjectTypeCustomLineCap,
-
- ObjectTypeMax = ObjectTypeCustomLineCap,
- ObjectTypeMin = ObjectTypeBrush
-};
-
-inline BOOL
-ObjectTypeIsValid(
- ObjectType type
- )
-{
- return ((type >= ObjectTypeMin) && (type <= ObjectTypeMax));
-}
-
-//---------------------------------------------------------------------------
-// EMF+ Records
-//---------------------------------------------------------------------------
-
-// We have to change the WMF record numbers so that they don't conflict with
-// the EMF and EMF+ record numbers.
-enum EmfPlusRecordType;
-#define GDIP_EMFPLUS_RECORD_BASE 0x00004000
-#define GDIP_WMF_RECORD_BASE 0x00010000
-#define GDIP_WMF_RECORD_TO_EMFPLUS(n) ((EmfPlusRecordType)((n) | GDIP_WMF_RECORD_BASE))
-#define GDIP_EMFPLUS_RECORD_TO_WMF(n) ((n) & (~GDIP_WMF_RECORD_BASE))
-#define GDIP_IS_WMF_RECORDTYPE(n) (((n) & GDIP_WMF_RECORD_BASE) != 0)
-
-enum EmfPlusRecordType
-{
- // Since we have to enumerate GDI records right along with GDI+ records,
- // we list all the GDI records here so that they can be part of the
- // same enumeration type which is used in the enumeration callback.
-
- WmfRecordTypeSetBkColor = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETBKCOLOR),
- WmfRecordTypeSetBkMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETBKMODE),
- WmfRecordTypeSetMapMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETMAPMODE),
- WmfRecordTypeSetROP2 = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETROP2),
- WmfRecordTypeSetRelAbs = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETRELABS),
- WmfRecordTypeSetPolyFillMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETPOLYFILLMODE),
- WmfRecordTypeSetStretchBltMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETSTRETCHBLTMODE),
- WmfRecordTypeSetTextCharExtra = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTCHAREXTRA),
- WmfRecordTypeSetTextColor = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTCOLOR),
- WmfRecordTypeSetTextJustification = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTJUSTIFICATION),
- WmfRecordTypeSetWindowOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETWINDOWORG),
- WmfRecordTypeSetWindowExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETWINDOWEXT),
- WmfRecordTypeSetViewportOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETVIEWPORTORG),
- WmfRecordTypeSetViewportExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETVIEWPORTEXT),
- WmfRecordTypeOffsetWindowOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_OFFSETWINDOWORG),
- WmfRecordTypeScaleWindowExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SCALEWINDOWEXT),
- WmfRecordTypeOffsetViewportOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_OFFSETVIEWPORTORG),
- WmfRecordTypeScaleViewportExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SCALEVIEWPORTEXT),
- WmfRecordTypeLineTo = GDIP_WMF_RECORD_TO_EMFPLUS(META_LINETO),
- WmfRecordTypeMoveTo = GDIP_WMF_RECORD_TO_EMFPLUS(META_MOVETO),
- WmfRecordTypeExcludeClipRect = GDIP_WMF_RECORD_TO_EMFPLUS(META_EXCLUDECLIPRECT),
- WmfRecordTypeIntersectClipRect = GDIP_WMF_RECORD_TO_EMFPLUS(META_INTERSECTCLIPRECT),
- WmfRecordTypeArc = GDIP_WMF_RECORD_TO_EMFPLUS(META_ARC),
- WmfRecordTypeEllipse = GDIP_WMF_RECORD_TO_EMFPLUS(META_ELLIPSE),
- WmfRecordTypeFloodFill = GDIP_WMF_RECORD_TO_EMFPLUS(META_FLOODFILL),
- WmfRecordTypePie = GDIP_WMF_RECORD_TO_EMFPLUS(META_PIE),
- WmfRecordTypeRectangle = GDIP_WMF_RECORD_TO_EMFPLUS(META_RECTANGLE),
- WmfRecordTypeRoundRect = GDIP_WMF_RECORD_TO_EMFPLUS(META_ROUNDRECT),
- WmfRecordTypePatBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_PATBLT),
- WmfRecordTypeSaveDC = GDIP_WMF_RECORD_TO_EMFPLUS(META_SAVEDC),
- WmfRecordTypeSetPixel = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETPIXEL),
- WmfRecordTypeOffsetClipRgn = GDIP_WMF_RECORD_TO_EMFPLUS(META_OFFSETCLIPRGN),
- WmfRecordTypeTextOut = GDIP_WMF_RECORD_TO_EMFPLUS(META_TEXTOUT),
- WmfRecordTypeBitBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_BITBLT),
- WmfRecordTypeStretchBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_STRETCHBLT),
- WmfRecordTypePolygon = GDIP_WMF_RECORD_TO_EMFPLUS(META_POLYGON),
- WmfRecordTypePolyline = GDIP_WMF_RECORD_TO_EMFPLUS(META_POLYLINE),
- WmfRecordTypeEscape = GDIP_WMF_RECORD_TO_EMFPLUS(META_ESCAPE),
- WmfRecordTypeRestoreDC = GDIP_WMF_RECORD_TO_EMFPLUS(META_RESTOREDC),
- WmfRecordTypeFillRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_FILLREGION),
- WmfRecordTypeFrameRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_FRAMEREGION),
- WmfRecordTypeInvertRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_INVERTREGION),
- WmfRecordTypePaintRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_PAINTREGION),
- WmfRecordTypeSelectClipRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_SELECTCLIPREGION),
- WmfRecordTypeSelectObject = GDIP_WMF_RECORD_TO_EMFPLUS(META_SELECTOBJECT),
- WmfRecordTypeSetTextAlign = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTALIGN),
- WmfRecordTypeDrawText = GDIP_WMF_RECORD_TO_EMFPLUS(0x062F), // META_DRAWTEXT
- WmfRecordTypeChord = GDIP_WMF_RECORD_TO_EMFPLUS(META_CHORD),
- WmfRecordTypeSetMapperFlags = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETMAPPERFLAGS),
- WmfRecordTypeExtTextOut = GDIP_WMF_RECORD_TO_EMFPLUS(META_EXTTEXTOUT),
- WmfRecordTypeSetDIBToDev = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETDIBTODEV),
- WmfRecordTypeSelectPalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_SELECTPALETTE),
- WmfRecordTypeRealizePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_REALIZEPALETTE),
- WmfRecordTypeAnimatePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_ANIMATEPALETTE),
- WmfRecordTypeSetPalEntries = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETPALENTRIES),
- WmfRecordTypePolyPolygon = GDIP_WMF_RECORD_TO_EMFPLUS(META_POLYPOLYGON),
- WmfRecordTypeResizePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_RESIZEPALETTE),
- WmfRecordTypeDIBBitBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_DIBBITBLT),
- WmfRecordTypeDIBStretchBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_DIBSTRETCHBLT),
- WmfRecordTypeDIBCreatePatternBrush = GDIP_WMF_RECORD_TO_EMFPLUS(META_DIBCREATEPATTERNBRUSH),
- WmfRecordTypeStretchDIB = GDIP_WMF_RECORD_TO_EMFPLUS(META_STRETCHDIB),
- WmfRecordTypeExtFloodFill = GDIP_WMF_RECORD_TO_EMFPLUS(META_EXTFLOODFILL),
- WmfRecordTypeSetLayout = GDIP_WMF_RECORD_TO_EMFPLUS(0x0149), // META_SETLAYOUT
- WmfRecordTypeResetDC = GDIP_WMF_RECORD_TO_EMFPLUS(0x014C), // META_RESETDC
- WmfRecordTypeStartDoc = GDIP_WMF_RECORD_TO_EMFPLUS(0x014D), // META_STARTDOC
- WmfRecordTypeStartPage = GDIP_WMF_RECORD_TO_EMFPLUS(0x004F), // META_STARTPAGE
- WmfRecordTypeEndPage = GDIP_WMF_RECORD_TO_EMFPLUS(0x0050), // META_ENDPAGE
- WmfRecordTypeAbortDoc = GDIP_WMF_RECORD_TO_EMFPLUS(0x0052), // META_ABORTDOC
- WmfRecordTypeEndDoc = GDIP_WMF_RECORD_TO_EMFPLUS(0x005E), // META_ENDDOC
- WmfRecordTypeDeleteObject = GDIP_WMF_RECORD_TO_EMFPLUS(META_DELETEOBJECT),
- WmfRecordTypeCreatePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEPALETTE),
- WmfRecordTypeCreateBrush = GDIP_WMF_RECORD_TO_EMFPLUS(0x00F8), // META_CREATEBRUSH
- WmfRecordTypeCreatePatternBrush = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEPATTERNBRUSH),
- WmfRecordTypeCreatePenIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEPENINDIRECT),
- WmfRecordTypeCreateFontIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEFONTINDIRECT),
- WmfRecordTypeCreateBrushIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEBRUSHINDIRECT),
- WmfRecordTypeCreateBitmapIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(0x02FD), // META_CREATEBITMAPINDIRECT
- WmfRecordTypeCreateBitmap = GDIP_WMF_RECORD_TO_EMFPLUS(0x06FE), // META_CREATEBITMAP
- WmfRecordTypeCreateRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEREGION),
-
- EmfRecordTypeHeader = EMR_HEADER,
- EmfRecordTypePolyBezier = EMR_POLYBEZIER,
- EmfRecordTypePolygon = EMR_POLYGON,
- EmfRecordTypePolyline = EMR_POLYLINE,
- EmfRecordTypePolyBezierTo = EMR_POLYBEZIERTO,
- EmfRecordTypePolyLineTo = EMR_POLYLINETO,
- EmfRecordTypePolyPolyline = EMR_POLYPOLYLINE,
- EmfRecordTypePolyPolygon = EMR_POLYPOLYGON,
- EmfRecordTypeSetWindowExtEx = EMR_SETWINDOWEXTEX,
- EmfRecordTypeSetWindowOrgEx = EMR_SETWINDOWORGEX,
- EmfRecordTypeSetViewportExtEx = EMR_SETVIEWPORTEXTEX,
- EmfRecordTypeSetViewportOrgEx = EMR_SETVIEWPORTORGEX,
- EmfRecordTypeSetBrushOrgEx = EMR_SETBRUSHORGEX,
- EmfRecordTypeEOF = EMR_EOF,
- EmfRecordTypeSetPixelV = EMR_SETPIXELV,
- EmfRecordTypeSetMapperFlags = EMR_SETMAPPERFLAGS,
- EmfRecordTypeSetMapMode = EMR_SETMAPMODE,
- EmfRecordTypeSetBkMode = EMR_SETBKMODE,
- EmfRecordTypeSetPolyFillMode = EMR_SETPOLYFILLMODE,
- EmfRecordTypeSetROP2 = EMR_SETROP2,
- EmfRecordTypeSetStretchBltMode = EMR_SETSTRETCHBLTMODE,
- EmfRecordTypeSetTextAlign = EMR_SETTEXTALIGN,
- EmfRecordTypeSetColorAdjustment = EMR_SETCOLORADJUSTMENT,
- EmfRecordTypeSetTextColor = EMR_SETTEXTCOLOR,
- EmfRecordTypeSetBkColor = EMR_SETBKCOLOR,
- EmfRecordTypeOffsetClipRgn = EMR_OFFSETCLIPRGN,
- EmfRecordTypeMoveToEx = EMR_MOVETOEX,
- EmfRecordTypeSetMetaRgn = EMR_SETMETARGN,
- EmfRecordTypeExcludeClipRect = EMR_EXCLUDECLIPRECT,
- EmfRecordTypeIntersectClipRect = EMR_INTERSECTCLIPRECT,
- EmfRecordTypeScaleViewportExtEx = EMR_SCALEVIEWPORTEXTEX,
- EmfRecordTypeScaleWindowExtEx = EMR_SCALEWINDOWEXTEX,
- EmfRecordTypeSaveDC = EMR_SAVEDC,
- EmfRecordTypeRestoreDC = EMR_RESTOREDC,
- EmfRecordTypeSetWorldTransform = EMR_SETWORLDTRANSFORM,
- EmfRecordTypeModifyWorldTransform = EMR_MODIFYWORLDTRANSFORM,
- EmfRecordTypeSelectObject = EMR_SELECTOBJECT,
- EmfRecordTypeCreatePen = EMR_CREATEPEN,
- EmfRecordTypeCreateBrushIndirect = EMR_CREATEBRUSHINDIRECT,
- EmfRecordTypeDeleteObject = EMR_DELETEOBJECT,
- EmfRecordTypeAngleArc = EMR_ANGLEARC,
- EmfRecordTypeEllipse = EMR_ELLIPSE,
- EmfRecordTypeRectangle = EMR_RECTANGLE,
- EmfRecordTypeRoundRect = EMR_ROUNDRECT,
- EmfRecordTypeArc = EMR_ARC,
- EmfRecordTypeChord = EMR_CHORD,
- EmfRecordTypePie = EMR_PIE,
- EmfRecordTypeSelectPalette = EMR_SELECTPALETTE,
- EmfRecordTypeCreatePalette = EMR_CREATEPALETTE,
- EmfRecordTypeSetPaletteEntries = EMR_SETPALETTEENTRIES,
- EmfRecordTypeResizePalette = EMR_RESIZEPALETTE,
- EmfRecordTypeRealizePalette = EMR_REALIZEPALETTE,
- EmfRecordTypeExtFloodFill = EMR_EXTFLOODFILL,
- EmfRecordTypeLineTo = EMR_LINETO,
- EmfRecordTypeArcTo = EMR_ARCTO,
- EmfRecordTypePolyDraw = EMR_POLYDRAW,
- EmfRecordTypeSetArcDirection = EMR_SETARCDIRECTION,
- EmfRecordTypeSetMiterLimit = EMR_SETMITERLIMIT,
- EmfRecordTypeBeginPath = EMR_BEGINPATH,
- EmfRecordTypeEndPath = EMR_ENDPATH,
- EmfRecordTypeCloseFigure = EMR_CLOSEFIGURE,
- EmfRecordTypeFillPath = EMR_FILLPATH,
- EmfRecordTypeStrokeAndFillPath = EMR_STROKEANDFILLPATH,
- EmfRecordTypeStrokePath = EMR_STROKEPATH,
- EmfRecordTypeFlattenPath = EMR_FLATTENPATH,
- EmfRecordTypeWidenPath = EMR_WIDENPATH,
- EmfRecordTypeSelectClipPath = EMR_SELECTCLIPPATH,
- EmfRecordTypeAbortPath = EMR_ABORTPATH,
- EmfRecordTypeReserved_069 = 69, // Not Used
- EmfRecordTypeGdiComment = EMR_GDICOMMENT,
- EmfRecordTypeFillRgn = EMR_FILLRGN,
- EmfRecordTypeFrameRgn = EMR_FRAMERGN,
- EmfRecordTypeInvertRgn = EMR_INVERTRGN,
- EmfRecordTypePaintRgn = EMR_PAINTRGN,
- EmfRecordTypeExtSelectClipRgn = EMR_EXTSELECTCLIPRGN,
- EmfRecordTypeBitBlt = EMR_BITBLT,
- EmfRecordTypeStretchBlt = EMR_STRETCHBLT,
- EmfRecordTypeMaskBlt = EMR_MASKBLT,
- EmfRecordTypePlgBlt = EMR_PLGBLT,
- EmfRecordTypeSetDIBitsToDevice = EMR_SETDIBITSTODEVICE,
- EmfRecordTypeStretchDIBits = EMR_STRETCHDIBITS,
- EmfRecordTypeExtCreateFontIndirect = EMR_EXTCREATEFONTINDIRECTW,
- EmfRecordTypeExtTextOutA = EMR_EXTTEXTOUTA,
- EmfRecordTypeExtTextOutW = EMR_EXTTEXTOUTW,
- EmfRecordTypePolyBezier16 = EMR_POLYBEZIER16,
- EmfRecordTypePolygon16 = EMR_POLYGON16,
- EmfRecordTypePolyline16 = EMR_POLYLINE16,
- EmfRecordTypePolyBezierTo16 = EMR_POLYBEZIERTO16,
- EmfRecordTypePolylineTo16 = EMR_POLYLINETO16,
- EmfRecordTypePolyPolyline16 = EMR_POLYPOLYLINE16,
- EmfRecordTypePolyPolygon16 = EMR_POLYPOLYGON16,
- EmfRecordTypePolyDraw16 = EMR_POLYDRAW16,
- EmfRecordTypeCreateMonoBrush = EMR_CREATEMONOBRUSH,
- EmfRecordTypeCreateDIBPatternBrushPt = EMR_CREATEDIBPATTERNBRUSHPT,
- EmfRecordTypeExtCreatePen = EMR_EXTCREATEPEN,
- EmfRecordTypePolyTextOutA = EMR_POLYTEXTOUTA,
- EmfRecordTypePolyTextOutW = EMR_POLYTEXTOUTW,
- EmfRecordTypeSetICMMode = 98, // EMR_SETICMMODE,
- EmfRecordTypeCreateColorSpace = 99, // EMR_CREATECOLORSPACE,
- EmfRecordTypeSetColorSpace = 100, // EMR_SETCOLORSPACE,
- EmfRecordTypeDeleteColorSpace = 101, // EMR_DELETECOLORSPACE,
- EmfRecordTypeGLSRecord = 102, // EMR_GLSRECORD,
- EmfRecordTypeGLSBoundedRecord = 103, // EMR_GLSBOUNDEDRECORD,
- EmfRecordTypePixelFormat = 104, // EMR_PIXELFORMAT,
- EmfRecordTypeDrawEscape = 105, // EMR_RESERVED_105,
- EmfRecordTypeExtEscape = 106, // EMR_RESERVED_106,
- EmfRecordTypeStartDoc = 107, // EMR_RESERVED_107,
- EmfRecordTypeSmallTextOut = 108, // EMR_RESERVED_108,
- EmfRecordTypeForceUFIMapping = 109, // EMR_RESERVED_109,
- EmfRecordTypeNamedEscape = 110, // EMR_RESERVED_110,
- EmfRecordTypeColorCorrectPalette = 111, // EMR_COLORCORRECTPALETTE,
- EmfRecordTypeSetICMProfileA = 112, // EMR_SETICMPROFILEA,
- EmfRecordTypeSetICMProfileW = 113, // EMR_SETICMPROFILEW,
- EmfRecordTypeAlphaBlend = 114, // EMR_ALPHABLEND,
- EmfRecordTypeSetLayout = 115, // EMR_SETLAYOUT,
- EmfRecordTypeTransparentBlt = 116, // EMR_TRANSPARENTBLT,
- EmfRecordTypeReserved_117 = 117, // Not Used
- EmfRecordTypeGradientFill = 118, // EMR_GRADIENTFILL,
- EmfRecordTypeSetLinkedUFIs = 119, // EMR_RESERVED_119,
- EmfRecordTypeSetTextJustification = 120, // EMR_RESERVED_120,
- EmfRecordTypeColorMatchToTargetW = 121, // EMR_COLORMATCHTOTARGETW,
- EmfRecordTypeCreateColorSpaceW = 122, // EMR_CREATECOLORSPACEW,
- EmfRecordTypeMax = 122,
- EmfRecordTypeMin = 1,
-
- // That is the END of the GDI EMF records.
-
- // Now we start the list of EMF+ records. We leave quite
- // a bit of room here for the addition of any new GDI
- // records that may be added later.
-
- EmfPlusRecordTypeInvalid = GDIP_EMFPLUS_RECORD_BASE,
- EmfPlusRecordTypeHeader,
- EmfPlusRecordTypeEndOfFile,
-
- EmfPlusRecordTypeComment,
-
- EmfPlusRecordTypeGetDC, // the application grabbed the metafile dc
-
- EmfPlusRecordTypeMultiFormatStart,
- EmfPlusRecordTypeMultiFormatSection,
- EmfPlusRecordTypeMultiFormatEnd,
-
- // For all persistent objects
- EmfPlusRecordTypeObject, // brush,pen,path,region,image,font,string-format
-
- // Drawing Records
- EmfPlusRecordTypeClear,
- EmfPlusRecordTypeFillRects,
- EmfPlusRecordTypeDrawRects,
- EmfPlusRecordTypeFillPolygon,
- EmfPlusRecordTypeDrawLines,
- EmfPlusRecordTypeFillEllipse,
- EmfPlusRecordTypeDrawEllipse,
- EmfPlusRecordTypeFillPie,
- EmfPlusRecordTypeDrawPie,
- EmfPlusRecordTypeDrawArc,
- EmfPlusRecordTypeFillRegion,
- EmfPlusRecordTypeFillPath,
- EmfPlusRecordTypeDrawPath,
- EmfPlusRecordTypeFillClosedCurve,
- EmfPlusRecordTypeDrawClosedCurve,
- EmfPlusRecordTypeDrawCurve,
- EmfPlusRecordTypeDrawBeziers,
- EmfPlusRecordTypeDrawImage,
- EmfPlusRecordTypeDrawImagePoints,
- EmfPlusRecordTypeDrawString,
-
- // Graphics State Records
- EmfPlusRecordTypeSetRenderingOrigin,
- EmfPlusRecordTypeSetAntiAliasMode,
- EmfPlusRecordTypeSetTextRenderingHint,
-#ifdef DCR_USE_NEW_188922
- EmfPlusRecordTypeSetTextContrast,
-#else
- EmfPlusRecordTypeSetGammaValue,
-#endif // DCR_USE_NEW_188922
- EmfPlusRecordTypeSetInterpolationMode,
- EmfPlusRecordTypeSetPixelOffsetMode,
- EmfPlusRecordTypeSetCompositingMode,
- EmfPlusRecordTypeSetCompositingQuality,
- EmfPlusRecordTypeSave,
- EmfPlusRecordTypeRestore,
- EmfPlusRecordTypeBeginContainer,
- EmfPlusRecordTypeBeginContainerNoParams,
- EmfPlusRecordTypeEndContainer,
- EmfPlusRecordTypeSetWorldTransform,
- EmfPlusRecordTypeResetWorldTransform,
- EmfPlusRecordTypeMultiplyWorldTransform,
- EmfPlusRecordTypeTranslateWorldTransform,
- EmfPlusRecordTypeScaleWorldTransform,
- EmfPlusRecordTypeRotateWorldTransform,
- EmfPlusRecordTypeSetPageTransform,
- EmfPlusRecordTypeResetClip,
- EmfPlusRecordTypeSetClipRect,
- EmfPlusRecordTypeSetClipPath,
- EmfPlusRecordTypeSetClipRegion,
- EmfPlusRecordTypeOffsetClip,
-
- // New record types must be added here (at the end) -- do not add above,
- // since that will invalidate previous metafiles!
- EmfPlusRecordTypeDrawDriverString,
-
- // Have this here so you don't need to keep changing the value of
- // EmfPlusRecordTypeMax every time you add a new record.
-
- EmfPlusRecordTotal,
-
- EmfPlusRecordTypeMax = EmfPlusRecordTotal-1,
- EmfPlusRecordTypeMin = EmfPlusRecordTypeHeader,
-};
-
-//---------------------------------------------------------------------------
-// StringFormatFlags
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// String format flags
-//
-// DirectionRightToLeft - For horizontal text, the reading order is
-// right to left. This value is called
-// the base embedding level by the Unicode
-// bidirectional engine.
-// For vertical text, columns are read from
-// right to left.
-// By default, horizontal or vertical text is
-// read from left to right.
-//
-// DirectionVertical - Individual lines of text are vertical. In
-// each line, characters progress from top to
-// bottom.
-// By default, lines of text are horizontal,
-// each new line below the previous line.
-//
-// NoFitBlackBox - Allows parts of glyphs to overhang the
-// bounding rectangle.
-// By default glyphs are first aligned
-// inside the margines, then any glyphs which
-// still overhang the bounding box are
-// repositioned to avoid any overhang.
-// For example when an italic
-// lower case letter f in a font such as
-// Garamond is aligned at the far left of a
-// rectangle, the lower part of the f will
-// reach slightly further left than the left
-// edge of the rectangle. Setting this flag
-// will ensure the character aligns visually
-// with the lines above and below, but may
-// cause some pixels outside the formatting
-// rectangle to be clipped or painted.
-//
-#ifndef DCR_USE_NEW_137252
-// NumberContextArabic - Causes any initial numeric in the string to
-// be analysed for bidirection layout as if
-// it was preceeded by Arabic text.
-//
-// DisableKashidaJustification - Arabic text will not be justified by the
-// insertion of kashidas (i.e. extending the
-// joining line between characters). Instead
-// Arabic script will be justified by the
-// widening of the whitespace between words.
-//
-#endif
-// DisplayFormatControl - Causes control characters such as the
-// left-to-right mark to be shown in the
-// output with a representative glyph.
-//
-#ifndef DCR_USE_NEW_137252
-// DisableKerning - Disables Truetype and OpenType kerning.
-//
-// DisableLigatures - Disables Truetype and OpenType ligatures.
-//
-// LayoutLegacyBidi - Causes the bidirection algorithm to use
-// slightly different classifications for
-// '+', '-' and '/' that make their layout
-// much closer to that expected by files
-// generated in Windows or by Windows
-// applications.
-//
-// NoChanges - A text imager created with this flag set
-// does not support those APIs that change
-// it's contents or formatting, but for most
-// simple text will be significantly faster in
-// performing measurement and drawing
-// functions.
-//
-#endif
-// NoFontFallback - Disables fallback to alternate fonts for
-// characters not supported in the requested
-// font. Any missing characters will be
-// be displayed with the fonts missing glyph,
-// usually an open square.
-//
-// NoWrap - Disables wrapping of text between lines
-// when formatting within a rectangle.
-// NoWrap is implied when a point is passed
-// instead of a rectangle, or when the
-// specified rectangle has a zero line length.
-//
-// NoClip - By default text is clipped to the
-// formatting rectangle. Setting NoClip
-// allows overhanging pixels to affect the
-// device outside the formatting rectangle.
-// Pixels at the end of the line may be
-// affected if the glyphs overhang their
-// cells, and either the NoFitBlackBox flag
-// has been set, or the glyph extends to far
-// to be fitted.
-// Pixels above/before the first line or
-// below/after the last line may be affected
-// if the glyphs extend beyond their cell
-// ascent / descent. This can occur rarely
-// with unusual diacritic mark combinations.
-
-//---------------------------------------------------------------------------
-
-enum StringFormatFlags
-{
- StringFormatFlagsDirectionRightToLeft = 0x00000001,
- StringFormatFlagsDirectionVertical = 0x00000002,
- StringFormatFlagsNoFitBlackBox = 0x00000004,
-#ifndef DCR_USE_NEW_137252
- StringFormatFlagsNumberContextArabic = 0x00000008,
- StringFormatFlagsDisableKashidaJustification = 0x00000010,
-#endif
- StringFormatFlagsDisplayFormatControl = 0x00000020,
-#ifndef DCR_USE_NEW_137252
- StringFormatFlagsDisableKerning = 0x00000040,
- StringFormatFlagsDisableLigatures = 0x00000080,
- StringFormatFlagsLayoutLegacyBidi = 0x00000100,
- StringFormatFlagsNoChanges = 0x00000200,
-#endif
- StringFormatFlagsNoFontFallback = 0x00000400,
- StringFormatFlagsMeasureTrailingSpaces = 0x00000800,
- StringFormatFlagsNoWrap = 0x00001000,
- StringFormatFlagsLineLimit = 0x00002000,
-
- StringFormatFlagsNoClip = 0x00004000
-};
-
-//---------------------------------------------------------------------------
-// StringTrimming
-//---------------------------------------------------------------------------
-
-enum StringTrimming {
- StringTrimmingNone = 0,
- StringTrimmingCharacter = 1,
- StringTrimmingWord = 2,
- StringTrimmingEllipsisCharacter = 3,
- StringTrimmingEllipsisWord = 4,
- StringTrimmingEllipsisPath = 5
-};
-
-#ifndef DCR_USE_NEW_137252
-//---------------------------------------------------------------------------
-// String units
-//
-// String units are like length units in CSS, they may be absolute, or
-// they may be relative to a font size.
-//
-//---------------------------------------------------------------------------
-
-enum StringUnit {
- StringUnitWorld = UnitWorld,
- StringUnitDisplay = UnitDisplay,
- StringUnitPixel = UnitPixel,
- StringUnitPoint = UnitPoint,
- StringUnitInch = UnitInch,
- StringUnitDocument = UnitDocument,
- StringUnitMillimeter = UnitMillimeter,
- StringUnitEm = 32
-};
-#endif
-
-#ifndef DCR_USE_NEW_152154
-//---------------------------------------------------------------------------
-// Line spacing flags
-//---------------------------------------------------------------------------
-
-enum LineSpacing {
- LineSpacingWorld = UnitWorld,
- LineSpacingDisplay = UnitDisplay,
- LineSpacingPixel = UnitPixel,
- LineSpacingPoint = UnitPoint,
- LineSpacingInch = UnitInch,
- LineSpacingDocument = UnitDocument,
- LineSpacingMillimeter = UnitMillimeter,
-
- LineSpacingRecommended = 32,
- LineSpacingAtLeast = 33,
- LineSpacingAtLeastMultiple = 34,
- LineSpacingCell = 35,
- LineSpacingCellAtLeast = 36,
- LineSpacingCellAtLeastMultiple = 37
-};
-
-/// The following methods of linespacing are relative to the font size
-//
-// =========== Method =========== =============== Relative to ===============
-//
-// LineSpacingRecommended recommended line spacing specified by font
-// LineSpacingAtLeast max(recommended, tallest glyph cell)
-// LineSpacingAtLeastMultiple smallest multiple of recommended big enough
-// for all glyph cells on the line
-// LineSpacingCell cell height
-// LineSpacingCellAtLeast max(font cell height, tallest glyph cell)
-// LineSpacingCellAtLeastMultiple smallest multiple of cell height big enough
-// for all glyph cells on the line
-#endif
-
-
-//---------------------------------------------------------------------------
-// National language digit substitution
-//---------------------------------------------------------------------------
-
-enum StringDigitSubstitute
-{
- StringDigitSubstituteUser = 0, // As NLS setting
- StringDigitSubstituteNone = 1,
- StringDigitSubstituteNational = 2,
- StringDigitSubstituteTraditional = 3
-};
-
-//---------------------------------------------------------------------------
-// Hotkey prefix interpretation
-//---------------------------------------------------------------------------
-
-enum HotkeyPrefix
-{
- HotkeyPrefixNone = 0,
- HotkeyPrefixShow = 1,
- HotkeyPrefixHide = 2
-};
-
-//---------------------------------------------------------------------------
-// Text alignment flags
-//---------------------------------------------------------------------------
-
-enum StringAlignment
-{
- // Left edge for left-to-right text,
- // right for right-to-left text,
- // and top for vertical
- StringAlignmentNear = 0,
- StringAlignmentCenter = 1,
- StringAlignmentFar = 2
-};
-
-//---------------------------------------------------------------------------
-// DriverStringOptions
-//---------------------------------------------------------------------------
-
-enum DriverStringOptions
-{
- DriverStringOptionsCmapLookup = 1,
- DriverStringOptionsVertical = 2,
- DriverStringOptionsRealizedAdvance = 4,
-#ifndef DCR_USE_NEW_137252
- DriverStringOptionsCompensateResolution = 8
-#endif
-};
-
-//---------------------------------------------------------------------------
-// Flush Intention flags
-//---------------------------------------------------------------------------
-
-enum FlushIntention
-{
- FlushIntentionFlush = 0, // Flush all batched rendering operations
- FlushIntentionSync = 1 // Flush all batched rendering operations
- // and wait for them to complete
-};
-
-#ifndef DCR_USE_NEW_175866
-
-//---------------------------------------------------------------------------
-// Window Change Notification types
-//---------------------------------------------------------------------------
-
-enum WindowNotifyEnum
-{
- WindowNotifyEnumEnable = 0,
- WindowNotifyEnumDisable,
- WindowNotifyEnumPalette,
- WindowNotifyEnumDisplay,
- WindowNotifyEnumSysColor
-};
-
-#endif
-
-//---------------------------------------------------------------------------
-// Image encoder parameter related types
-//---------------------------------------------------------------------------
-
-#ifdef DCR_USE_NEW_145804
-enum EncoderParameterValueType
-{
- EncoderParameterValueTypeByte = 1, // 8-bit unsigned int
- EncoderParameterValueTypeASCII = 2, // 8-bit byte containing one 7-bit ASCII
- // code. NULL terminated.
- EncoderParameterValueTypeShort = 3, // 16-bit unsigned int
- EncoderParameterValueTypeLong = 4, // 32-bit unsigned int
- EncoderParameterValueTypeRational = 5, // Two Longs. The first Long is the
- // numerator, the second Long expresses the
- // denomintor.
- EncoderParameterValueTypeLongRange = 6, // Two longs which specify a range of
- // integer values. The first Long specifies
- // the lower end and the second one
- // specifies the higher end. All values
- // are inclusive at both ends
- EncoderParameterValueTypeUndefined = 7, // 8-bit byte that can take any value
- // depending on field definition
- EncoderParameterValueTypeRationalRange = 8 // Two Rationals. The first Rational
- // specifies the lower end and the second
- // specifies the higher end. All values
- // are inclusive at both ends
-};
-#else
-enum ValueType
-{
- ValueTypeByte = 1, // 8-bit unsigned int
- ValueTypeASCII = 2, // 8-bit byte containing one 7-bit ASCII
- // code. NULL terminated.
- ValueTypeShort = 3, // 16-bit unsigned int
- ValueTypeLong = 4, // 32-bit unsigned int
- ValueTypeRational = 5, // Two Longs. The first Long is the
- // numerator, the second Long expresses the
- // denomintor.
- ValueTypeLongRange = 6, // Two longs which specify a range of
- // integer values. The first Long specifies
- // the lower end and the second one
- // specifies the higher end. All values
- // are inclusive at both ends
- ValueTypeUndefined = 7, // 8-bit byte that can take any value
- // depending on field definition
- ValueTypeRationalRange = 8 // Two Rationals. The first Rational
- // specifies the lower end and the second
- // specifies the higher end. All values
- // are inclusive at both ends
-};
-#endif
-
-//---------------------------------------------------------------------------
-// Image encoder value types
-//---------------------------------------------------------------------------
-
-enum EncoderValue
-{
- EncoderValueColorTypeCMYK,
- EncoderValueColorTypeYCCK,
- EncoderValueCompressionLZW,
- EncoderValueCompressionCCITT3,
- EncoderValueCompressionCCITT4,
- EncoderValueCompressionRle,
- EncoderValueCompressionNone,
- EncoderValueScanMethodInterlaced,
- EncoderValueScanMethodNonInterlaced,
- EncoderValueVersionGif87,
- EncoderValueVersionGif89,
- EncoderValueRenderProgressive,
- EncoderValueRenderNonProgressive,
- EncoderValueTransformRotate90,
- EncoderValueTransformRotate180,
- EncoderValueTransformRotate270,
- EncoderValueTransformFlipHorizontal,
- EncoderValueTransformFlipVertical,
- #ifdef DCR_USE_NEW_140861
- EncoderValueMultiFrame,
- #else
- EncodeValueMultiFrame,
- #endif
- EncoderValueLastFrame,
- EncoderValueFlush,
- #ifdef DCR_USE_NEW_140861
- EncoderValueFrameDimensionTime,
- EncoderValueFrameDimensionResolution,
- EncoderValueFrameDimensionPage
- #else
- EncodeValueFrameDimensionTime,
- EncodeValueFrameDimensionResolution,
- EncodeValueFrameDimensionPage
- #endif
-};
-
-//---------------------------------------------------------------------------
-// Graphics layout values (support for Middle East localization)
-//---------------------------------------------------------------------------
-
-enum GraphicsLayout
-{
- GraphicsLayoutNormal,
- GraphicsLayoutMirrored,
- GraphicsLayoutMirroredIgnoreImages,
- GraphicsLayoutMirroredForceImages
-};
-
-//---------------------------------------------------------------------------
-// Image layout values (support for Middle East localization)
-//---------------------------------------------------------------------------
-
-enum ImageLayout
-{
- ImageLayoutNormal,
- ImageLayoutIgnoreMirrored
-};
-
-enum EmfToWmfBitsFlags
-{
- EmfToWmfBitsFlagsDefault = 0x00000000,
- EmfToWmfBitsFlagsEmbedEmf = 0x00000001,
- EmfToWmfBitsFlagsIncludeAPM = 0x00000002,
- EmfToWmfBitsFlagsNoXORClip = 0x00000004
-};
-
-#endif // !_GDIPLUSENUMS_H
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusEnums.h
+*
+* Abstract:
+*
+* Various enumeration types
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSENUMS_H
+#define _GDIPLUSENUMS_H
+
+
+//--------------------------------------------------------------------------
+// Default bezier flattening tolerance in device pixels.
+//--------------------------------------------------------------------------
+
+const float FlatnessDefault = 1.0f/4.0f;
+
+//--------------------------------------------------------------------------
+// Graphics and Container State cookies
+//--------------------------------------------------------------------------
+
+typedef UINT GraphicsState;
+typedef UINT GraphicsContainer;
+
+//--------------------------------------------------------------------------
+// Fill mode constants
+//--------------------------------------------------------------------------
+
+enum FillMode
+{
+ FillModeAlternate, // 0
+ FillModeWinding // 1
+};
+
+//--------------------------------------------------------------------------
+// Quality mode constants
+//--------------------------------------------------------------------------
+
+enum QualityMode
+{
+ QualityModeInvalid = -1,
+ QualityModeDefault = 0,
+ QualityModeLow = 1, // for apps that need the best performance
+ QualityModeHigh = 2 // for apps that need the best rendering quality
+};
+
+//--------------------------------------------------------------------------
+// Alpha compositing mode constants
+//--------------------------------------------------------------------------
+
+enum CompositingMode
+{
+ CompositingModeSourceOver, // 0
+ CompositingModeSourceCopy // 1
+};
+
+//--------------------------------------------------------------------------
+// Alpha compositing quality constants
+//--------------------------------------------------------------------------
+
+enum CompositingQuality
+{
+ CompositingQualityInvalid = QualityModeInvalid,
+ CompositingQualityDefault = QualityModeDefault,
+ CompositingQualityHighSpeed = QualityModeLow,
+ CompositingQualityHighQuality = QualityModeHigh,
+ CompositingQualityGammaCorrected,
+ CompositingQualityAssumeLinear
+};
+
+//--------------------------------------------------------------------------
+// Unit constants
+//--------------------------------------------------------------------------
+
+enum Unit
+{
+ UnitWorld, // 0 -- World coordinate (non-physical unit)
+ UnitDisplay, // 1 -- Variable -- for PageTransform only
+ UnitPixel, // 2 -- Each unit is one device pixel.
+ UnitPoint, // 3 -- Each unit is a printer's point, or 1/72 inch.
+ UnitInch, // 4 -- Each unit is 1 inch.
+ UnitDocument, // 5 -- Each unit is 1/300 inch.
+ UnitMillimeter // 6 -- Each unit is 1 millimeter.
+};
+
+//--------------------------------------------------------------------------
+// MetafileFrameUnit
+//
+// The frameRect for creating a metafile can be specified in any of these
+// units. There is an extra frame unit value (MetafileFrameUnitGdi) so
+// that units can be supplied in the same units that GDI expects for
+// frame rects -- these units are in .01 (1/100ths) millimeter units
+// as defined by GDI.
+//--------------------------------------------------------------------------
+enum MetafileFrameUnit
+{
+ MetafileFrameUnitPixel = UnitPixel,
+ MetafileFrameUnitPoint = UnitPoint,
+ MetafileFrameUnitInch = UnitInch,
+ MetafileFrameUnitDocument = UnitDocument,
+ MetafileFrameUnitMillimeter = UnitMillimeter,
+ MetafileFrameUnitGdi // GDI compatible .01 MM units
+};
+
+//--------------------------------------------------------------------------
+// Coordinate space identifiers
+//--------------------------------------------------------------------------
+
+enum CoordinateSpace
+{
+ CoordinateSpaceWorld, // 0
+ CoordinateSpacePage, // 1
+ CoordinateSpaceDevice // 2
+};
+
+//--------------------------------------------------------------------------
+// Various wrap modes for brushes
+//--------------------------------------------------------------------------
+
+enum WrapMode
+{
+ WrapModeTile, // 0
+ WrapModeTileFlipX, // 1
+ WrapModeTileFlipY, // 2
+ WrapModeTileFlipXY, // 3
+ WrapModeClamp // 4
+};
+
+//--------------------------------------------------------------------------
+// Various hatch styles
+//--------------------------------------------------------------------------
+
+enum HatchStyle
+{
+ HatchStyleHorizontal, // 0
+ HatchStyleVertical, // 1
+ HatchStyleForwardDiagonal, // 2
+ HatchStyleBackwardDiagonal, // 3
+ HatchStyleCross, // 4
+ HatchStyleDiagonalCross, // 5
+ HatchStyle05Percent, // 6
+ HatchStyle10Percent, // 7
+ HatchStyle20Percent, // 8
+ HatchStyle25Percent, // 9
+ HatchStyle30Percent, // 10
+ HatchStyle40Percent, // 11
+ HatchStyle50Percent, // 12
+ HatchStyle60Percent, // 13
+ HatchStyle70Percent, // 14
+ HatchStyle75Percent, // 15
+ HatchStyle80Percent, // 16
+ HatchStyle90Percent, // 17
+ HatchStyleLightDownwardDiagonal, // 18
+ HatchStyleLightUpwardDiagonal, // 19
+ HatchStyleDarkDownwardDiagonal, // 20
+ HatchStyleDarkUpwardDiagonal, // 21
+ HatchStyleWideDownwardDiagonal, // 22
+ HatchStyleWideUpwardDiagonal, // 23
+ HatchStyleLightVertical, // 24
+ HatchStyleLightHorizontal, // 25
+ HatchStyleNarrowVertical, // 26
+ HatchStyleNarrowHorizontal, // 27
+ HatchStyleDarkVertical, // 28
+ HatchStyleDarkHorizontal, // 29
+ HatchStyleDashedDownwardDiagonal, // 30
+ HatchStyleDashedUpwardDiagonal, // 31
+ HatchStyleDashedHorizontal, // 32
+ HatchStyleDashedVertical, // 33
+ HatchStyleSmallConfetti, // 34
+ HatchStyleLargeConfetti, // 35
+ HatchStyleZigZag, // 36
+ HatchStyleWave, // 37
+ HatchStyleDiagonalBrick, // 38
+ HatchStyleHorizontalBrick, // 39
+ HatchStyleWeave, // 40
+ HatchStylePlaid, // 41
+ HatchStyleDivot, // 42
+ HatchStyleDottedGrid, // 43
+ HatchStyleDottedDiamond, // 44
+ HatchStyleShingle, // 45
+ HatchStyleTrellis, // 46
+ HatchStyleSphere, // 47
+ HatchStyleSmallGrid, // 48
+ HatchStyleSmallCheckerBoard, // 49
+ HatchStyleLargeCheckerBoard, // 50
+ HatchStyleOutlinedDiamond, // 51
+ HatchStyleSolidDiamond, // 52
+
+ HatchStyleTotal, // must be after all unique hatch styles
+
+ HatchStyleLargeGrid = HatchStyleCross, // 4 an alias for the cross style
+
+ HatchStyleMin = HatchStyleHorizontal,
+ HatchStyleMax = HatchStyleTotal - 1,
+};
+
+//--------------------------------------------------------------------------
+// Dash style constants
+//--------------------------------------------------------------------------
+
+enum DashStyle
+{
+ DashStyleSolid, // 0
+ DashStyleDash, // 1
+ DashStyleDot, // 2
+ DashStyleDashDot, // 3
+ DashStyleDashDotDot, // 4
+ DashStyleCustom // 5
+};
+
+//--------------------------------------------------------------------------
+// Dash cap constants
+//--------------------------------------------------------------------------
+
+enum DashCap
+{
+ DashCapFlat = 0,
+ DashCapRound = 2,
+ DashCapTriangle = 3
+};
+
+//--------------------------------------------------------------------------
+// Line cap constants (only the lowest 8 bits are used).
+//--------------------------------------------------------------------------
+
+enum LineCap
+{
+ LineCapFlat = 0,
+ LineCapSquare = 1,
+ LineCapRound = 2,
+ LineCapTriangle = 3,
+
+ LineCapNoAnchor = 0x10, // corresponds to flat cap
+ LineCapSquareAnchor = 0x11, // corresponds to square cap
+ LineCapRoundAnchor = 0x12, // corresponds to round cap
+ LineCapDiamondAnchor = 0x13, // corresponds to triangle cap
+ LineCapArrowAnchor = 0x14, // no correspondence
+
+ LineCapCustom = 0xff, // custom cap
+
+ LineCapAnchorMask = 0xf0 // mask to check for anchor or not.
+};
+
+//--------------------------------------------------------------------------
+// Custom Line cap type constants
+//--------------------------------------------------------------------------
+
+enum CustomLineCapType
+{
+ CustomLineCapTypeDefault = 0,
+ CustomLineCapTypeAdjustableArrow = 1
+};
+
+//--------------------------------------------------------------------------
+// Line join constants
+//--------------------------------------------------------------------------
+
+enum LineJoin
+{
+ LineJoinMiter = 0,
+ LineJoinBevel = 1,
+ LineJoinRound = 2,
+ LineJoinMiterClipped = 3
+};
+
+//--------------------------------------------------------------------------
+// Path point types (only the lowest 8 bits are used.)
+// The lowest 3 bits are interpreted as point type
+// The higher 5 bits are reserved for flags.
+//--------------------------------------------------------------------------
+
+enum PathPointType
+{
+ PathPointTypeStart = 0, // move
+ PathPointTypeLine = 1, // line
+ PathPointTypeBezier = 3, // default Beizer (= cubic Bezier)
+ PathPointTypePathTypeMask = 0x07, // type mask (lowest 3 bits).
+ PathPointTypeDashMode = 0x10, // currently in dash mode.
+ PathPointTypePathMarker = 0x20, // a marker for the path.
+ PathPointTypeCloseSubpath = 0x80, // closed flag
+
+ // Path types used for advanced path.
+
+ PathPointTypeBezier2 = 2, // quadratic Beizer
+ PathPointTypeBezier3 = 3, // cubic Bezier
+ PathPointTypeBezier4 = 4, // quartic (4th order) Beizer
+ PathPointTypeBezier5 = 5, // quintic (5th order) Bezier
+ PathPointTypeBezier6 = 6 // hexaic (6th order) Bezier
+};
+
+
+//--------------------------------------------------------------------------
+// WarpMode constants
+//--------------------------------------------------------------------------
+
+enum WarpMode
+{
+ WarpModePerspective, // 0
+ WarpModeBilinear // 1
+};
+
+//--------------------------------------------------------------------------
+// LineGradient Mode
+//--------------------------------------------------------------------------
+
+enum LinearGradientMode
+{
+ LinearGradientModeHorizontal, // 0
+ LinearGradientModeVertical, // 1
+ LinearGradientModeForwardDiagonal, // 2
+ LinearGradientModeBackwardDiagonal // 3
+};
+
+//--------------------------------------------------------------------------
+// Region Comine Modes
+//--------------------------------------------------------------------------
+
+enum CombineMode
+{
+ CombineModeReplace, // 0
+ CombineModeIntersect, // 1
+ CombineModeUnion, // 2
+ CombineModeXor, // 3
+ CombineModeExclude, // 4
+ CombineModeComplement // 5 (does exclude from)
+};
+
+//--------------------------------------------------------------------------
+ // Image types
+//--------------------------------------------------------------------------
+
+enum ImageType
+{
+ ImageTypeUnknown, // 0
+ ImageTypeBitmap, // 1
+ ImageTypeMetafile // 2
+};
+
+//--------------------------------------------------------------------------
+// Interpolation modes
+//--------------------------------------------------------------------------
+
+enum InterpolationMode
+{
+ InterpolationModeInvalid = QualityModeInvalid,
+ InterpolationModeDefault = QualityModeDefault,
+ InterpolationModeLowQuality = QualityModeLow,
+ InterpolationModeHighQuality = QualityModeHigh,
+ InterpolationModeBilinear,
+ InterpolationModeBicubic,
+ InterpolationModeNearestNeighbor,
+ InterpolationModeHighQualityBilinear,
+ InterpolationModeHighQualityBicubic
+};
+
+//--------------------------------------------------------------------------
+// Pen types
+//--------------------------------------------------------------------------
+enum PenAlignment
+{
+ PenAlignmentCenter = 0,
+ PenAlignmentInset = 1,
+ PenAlignmentOutset = 2,
+ PenAlignmentLeft = 3,
+ PenAlignmentRight = 4
+};
+
+//--------------------------------------------------------------------------
+// Brush types
+//--------------------------------------------------------------------------
+
+enum BrushType
+{
+ BrushTypeSolidColor = 0,
+ BrushTypeHatchFill = 1,
+ BrushTypeTextureFill = 2,
+ BrushTypePathGradient = 3,
+ BrushTypeLinearGradient = 4
+};
+
+//--------------------------------------------------------------------------
+// Pen's Fill types
+//--------------------------------------------------------------------------
+
+enum PenType
+{
+ PenTypeSolidColor = BrushTypeSolidColor,
+ PenTypeHatchFill = BrushTypeHatchFill,
+ PenTypeTextureFill = BrushTypeTextureFill,
+ PenTypePathGradient = BrushTypePathGradient,
+ PenTypeLinearGradient = BrushTypeLinearGradient,
+ PenTypeUnknown = -1
+};
+
+//--------------------------------------------------------------------------
+// Matrix Order
+//--------------------------------------------------------------------------
+
+enum MatrixOrder
+{
+ MatrixOrderPrepend = 0,
+ MatrixOrderAppend = 1
+};
+
+//--------------------------------------------------------------------------
+// Generic font families
+//--------------------------------------------------------------------------
+
+enum GenericFontFamily
+{
+ GenericFontFamilySerif,
+ GenericFontFamilySansSerif,
+ GenericFontFamilyMonospace
+
+};
+
+//--------------------------------------------------------------------------
+// FontStyle: face types and common styles
+//--------------------------------------------------------------------------
+
+// These should probably be flags
+
+// Must have:
+// Regular = 0
+// Bold = 1
+// Italic = 2
+// BoldItalic = 3
+
+enum FontStyle
+{
+ FontStyleRegular = 0,
+ FontStyleBold = 1,
+ FontStyleItalic = 2,
+ FontStyleBoldItalic = 3,
+ FontStyleUnderline = 4,
+ FontStyleStrikeout = 8
+};
+
+//---------------------------------------------------------------------------
+// Smoothing Mode
+//---------------------------------------------------------------------------
+
+enum SmoothingMode
+{
+ SmoothingModeInvalid = QualityModeInvalid,
+ SmoothingModeDefault = QualityModeDefault,
+ SmoothingModeHighSpeed = QualityModeLow,
+ SmoothingModeHighQuality = QualityModeHigh,
+ SmoothingModeNone,
+ SmoothingModeAntiAlias
+};
+
+//---------------------------------------------------------------------------
+// Pixel Format Mode
+//---------------------------------------------------------------------------
+
+enum PixelOffsetMode
+{
+ PixelOffsetModeInvalid = QualityModeInvalid,
+ PixelOffsetModeDefault = QualityModeDefault,
+ PixelOffsetModeHighSpeed = QualityModeLow,
+ PixelOffsetModeHighQuality = QualityModeHigh,
+ PixelOffsetModeNone, // no pixel offset
+ PixelOffsetModeHalf // offset by -0.5, -0.5 for fast anti-alias perf
+};
+
+//---------------------------------------------------------------------------
+// Text Rendering Hint
+//---------------------------------------------------------------------------
+
+enum TextRenderingHint
+{
+#ifdef DCR_USE_NEW_186764
+ TextRenderingHintSystemDefault = 0, // Glyph with system default rendering hint
+ TextRenderingHintSingleBitPerPixelGridFit, // Glyph bitmap with hinting
+#else
+ TextRenderingHintSingleBitPerPixelGridFit = 0, // Glyph bitmap with hinting
+#endif // DCR_USE_NEW_186764
+ TextRenderingHintSingleBitPerPixel, // Glyph bitmap without hinting
+ TextRenderingHintAntiAliasGridFit, // Glyph anti-alias bitmap with hinting
+ TextRenderingHintAntiAlias, // Glyph anti-alias bitmap without hinting
+ TextRenderingHintClearTypeGridFit // Glyph CT bitmap with hinting
+};
+
+//---------------------------------------------------------------------------
+// Metafile Types
+//---------------------------------------------------------------------------
+enum MetafileType
+{
+ MetafileTypeInvalid, // Invalid metafile
+ MetafileTypeWmf, // Standard WMF
+ MetafileTypeWmfAldus, // Aldus Placeable Metafile format
+ MetafileTypeEmf, // EMF (not EMF+)
+ MetafileTypeEmfPlusOnly, // EMF+ without dual, down-level records
+ MetafileTypeEmfPlusDual // EMF+ with dual, down-level records
+};
+
+// Specifies the type of EMF to record
+enum EmfType
+{
+ EmfTypeEmfOnly = MetafileTypeEmf, // no EMF+, only EMF
+ EmfTypeEmfPlusOnly = MetafileTypeEmfPlusOnly, // no EMF, only EMF+
+ EmfTypeEmfPlusDual = MetafileTypeEmfPlusDual // both EMF+ and EMF
+};
+
+// All persistent objects must have a type listed here
+enum ObjectType
+{
+ ObjectTypeInvalid,
+ ObjectTypeBrush,
+ ObjectTypePen,
+ ObjectTypePath,
+ ObjectTypeRegion,
+ ObjectTypeImage,
+ ObjectTypeFont,
+ ObjectTypeStringFormat,
+ ObjectTypeImageAttributes,
+ ObjectTypeCustomLineCap,
+
+ ObjectTypeMax = ObjectTypeCustomLineCap,
+ ObjectTypeMin = ObjectTypeBrush
+};
+
+inline BOOL
+ObjectTypeIsValid(
+ ObjectType type
+ )
+{
+ return ((type >= ObjectTypeMin) && (type <= ObjectTypeMax));
+}
+
+//---------------------------------------------------------------------------
+// EMF+ Records
+//---------------------------------------------------------------------------
+
+// We have to change the WMF record numbers so that they don't conflict with
+// the EMF and EMF+ record numbers.
+enum EmfPlusRecordType;
+#define GDIP_EMFPLUS_RECORD_BASE 0x00004000
+#define GDIP_WMF_RECORD_BASE 0x00010000
+#define GDIP_WMF_RECORD_TO_EMFPLUS(n) ((EmfPlusRecordType)((n) | GDIP_WMF_RECORD_BASE))
+#define GDIP_EMFPLUS_RECORD_TO_WMF(n) ((n) & (~GDIP_WMF_RECORD_BASE))
+#define GDIP_IS_WMF_RECORDTYPE(n) (((n) & GDIP_WMF_RECORD_BASE) != 0)
+
+enum EmfPlusRecordType
+{
+ // Since we have to enumerate GDI records right along with GDI+ records,
+ // we list all the GDI records here so that they can be part of the
+ // same enumeration type which is used in the enumeration callback.
+
+ WmfRecordTypeSetBkColor = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETBKCOLOR),
+ WmfRecordTypeSetBkMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETBKMODE),
+ WmfRecordTypeSetMapMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETMAPMODE),
+ WmfRecordTypeSetROP2 = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETROP2),
+ WmfRecordTypeSetRelAbs = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETRELABS),
+ WmfRecordTypeSetPolyFillMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETPOLYFILLMODE),
+ WmfRecordTypeSetStretchBltMode = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETSTRETCHBLTMODE),
+ WmfRecordTypeSetTextCharExtra = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTCHAREXTRA),
+ WmfRecordTypeSetTextColor = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTCOLOR),
+ WmfRecordTypeSetTextJustification = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTJUSTIFICATION),
+ WmfRecordTypeSetWindowOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETWINDOWORG),
+ WmfRecordTypeSetWindowExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETWINDOWEXT),
+ WmfRecordTypeSetViewportOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETVIEWPORTORG),
+ WmfRecordTypeSetViewportExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETVIEWPORTEXT),
+ WmfRecordTypeOffsetWindowOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_OFFSETWINDOWORG),
+ WmfRecordTypeScaleWindowExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SCALEWINDOWEXT),
+ WmfRecordTypeOffsetViewportOrg = GDIP_WMF_RECORD_TO_EMFPLUS(META_OFFSETVIEWPORTORG),
+ WmfRecordTypeScaleViewportExt = GDIP_WMF_RECORD_TO_EMFPLUS(META_SCALEVIEWPORTEXT),
+ WmfRecordTypeLineTo = GDIP_WMF_RECORD_TO_EMFPLUS(META_LINETO),
+ WmfRecordTypeMoveTo = GDIP_WMF_RECORD_TO_EMFPLUS(META_MOVETO),
+ WmfRecordTypeExcludeClipRect = GDIP_WMF_RECORD_TO_EMFPLUS(META_EXCLUDECLIPRECT),
+ WmfRecordTypeIntersectClipRect = GDIP_WMF_RECORD_TO_EMFPLUS(META_INTERSECTCLIPRECT),
+ WmfRecordTypeArc = GDIP_WMF_RECORD_TO_EMFPLUS(META_ARC),
+ WmfRecordTypeEllipse = GDIP_WMF_RECORD_TO_EMFPLUS(META_ELLIPSE),
+ WmfRecordTypeFloodFill = GDIP_WMF_RECORD_TO_EMFPLUS(META_FLOODFILL),
+ WmfRecordTypePie = GDIP_WMF_RECORD_TO_EMFPLUS(META_PIE),
+ WmfRecordTypeRectangle = GDIP_WMF_RECORD_TO_EMFPLUS(META_RECTANGLE),
+ WmfRecordTypeRoundRect = GDIP_WMF_RECORD_TO_EMFPLUS(META_ROUNDRECT),
+ WmfRecordTypePatBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_PATBLT),
+ WmfRecordTypeSaveDC = GDIP_WMF_RECORD_TO_EMFPLUS(META_SAVEDC),
+ WmfRecordTypeSetPixel = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETPIXEL),
+ WmfRecordTypeOffsetClipRgn = GDIP_WMF_RECORD_TO_EMFPLUS(META_OFFSETCLIPRGN),
+ WmfRecordTypeTextOut = GDIP_WMF_RECORD_TO_EMFPLUS(META_TEXTOUT),
+ WmfRecordTypeBitBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_BITBLT),
+ WmfRecordTypeStretchBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_STRETCHBLT),
+ WmfRecordTypePolygon = GDIP_WMF_RECORD_TO_EMFPLUS(META_POLYGON),
+ WmfRecordTypePolyline = GDIP_WMF_RECORD_TO_EMFPLUS(META_POLYLINE),
+ WmfRecordTypeEscape = GDIP_WMF_RECORD_TO_EMFPLUS(META_ESCAPE),
+ WmfRecordTypeRestoreDC = GDIP_WMF_RECORD_TO_EMFPLUS(META_RESTOREDC),
+ WmfRecordTypeFillRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_FILLREGION),
+ WmfRecordTypeFrameRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_FRAMEREGION),
+ WmfRecordTypeInvertRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_INVERTREGION),
+ WmfRecordTypePaintRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_PAINTREGION),
+ WmfRecordTypeSelectClipRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_SELECTCLIPREGION),
+ WmfRecordTypeSelectObject = GDIP_WMF_RECORD_TO_EMFPLUS(META_SELECTOBJECT),
+ WmfRecordTypeSetTextAlign = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETTEXTALIGN),
+ WmfRecordTypeDrawText = GDIP_WMF_RECORD_TO_EMFPLUS(0x062F), // META_DRAWTEXT
+ WmfRecordTypeChord = GDIP_WMF_RECORD_TO_EMFPLUS(META_CHORD),
+ WmfRecordTypeSetMapperFlags = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETMAPPERFLAGS),
+ WmfRecordTypeExtTextOut = GDIP_WMF_RECORD_TO_EMFPLUS(META_EXTTEXTOUT),
+ WmfRecordTypeSetDIBToDev = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETDIBTODEV),
+ WmfRecordTypeSelectPalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_SELECTPALETTE),
+ WmfRecordTypeRealizePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_REALIZEPALETTE),
+ WmfRecordTypeAnimatePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_ANIMATEPALETTE),
+ WmfRecordTypeSetPalEntries = GDIP_WMF_RECORD_TO_EMFPLUS(META_SETPALENTRIES),
+ WmfRecordTypePolyPolygon = GDIP_WMF_RECORD_TO_EMFPLUS(META_POLYPOLYGON),
+ WmfRecordTypeResizePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_RESIZEPALETTE),
+ WmfRecordTypeDIBBitBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_DIBBITBLT),
+ WmfRecordTypeDIBStretchBlt = GDIP_WMF_RECORD_TO_EMFPLUS(META_DIBSTRETCHBLT),
+ WmfRecordTypeDIBCreatePatternBrush = GDIP_WMF_RECORD_TO_EMFPLUS(META_DIBCREATEPATTERNBRUSH),
+ WmfRecordTypeStretchDIB = GDIP_WMF_RECORD_TO_EMFPLUS(META_STRETCHDIB),
+ WmfRecordTypeExtFloodFill = GDIP_WMF_RECORD_TO_EMFPLUS(META_EXTFLOODFILL),
+ WmfRecordTypeSetLayout = GDIP_WMF_RECORD_TO_EMFPLUS(0x0149), // META_SETLAYOUT
+ WmfRecordTypeResetDC = GDIP_WMF_RECORD_TO_EMFPLUS(0x014C), // META_RESETDC
+ WmfRecordTypeStartDoc = GDIP_WMF_RECORD_TO_EMFPLUS(0x014D), // META_STARTDOC
+ WmfRecordTypeStartPage = GDIP_WMF_RECORD_TO_EMFPLUS(0x004F), // META_STARTPAGE
+ WmfRecordTypeEndPage = GDIP_WMF_RECORD_TO_EMFPLUS(0x0050), // META_ENDPAGE
+ WmfRecordTypeAbortDoc = GDIP_WMF_RECORD_TO_EMFPLUS(0x0052), // META_ABORTDOC
+ WmfRecordTypeEndDoc = GDIP_WMF_RECORD_TO_EMFPLUS(0x005E), // META_ENDDOC
+ WmfRecordTypeDeleteObject = GDIP_WMF_RECORD_TO_EMFPLUS(META_DELETEOBJECT),
+ WmfRecordTypeCreatePalette = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEPALETTE),
+ WmfRecordTypeCreateBrush = GDIP_WMF_RECORD_TO_EMFPLUS(0x00F8), // META_CREATEBRUSH
+ WmfRecordTypeCreatePatternBrush = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEPATTERNBRUSH),
+ WmfRecordTypeCreatePenIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEPENINDIRECT),
+ WmfRecordTypeCreateFontIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEFONTINDIRECT),
+ WmfRecordTypeCreateBrushIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEBRUSHINDIRECT),
+ WmfRecordTypeCreateBitmapIndirect = GDIP_WMF_RECORD_TO_EMFPLUS(0x02FD), // META_CREATEBITMAPINDIRECT
+ WmfRecordTypeCreateBitmap = GDIP_WMF_RECORD_TO_EMFPLUS(0x06FE), // META_CREATEBITMAP
+ WmfRecordTypeCreateRegion = GDIP_WMF_RECORD_TO_EMFPLUS(META_CREATEREGION),
+
+ EmfRecordTypeHeader = EMR_HEADER,
+ EmfRecordTypePolyBezier = EMR_POLYBEZIER,
+ EmfRecordTypePolygon = EMR_POLYGON,
+ EmfRecordTypePolyline = EMR_POLYLINE,
+ EmfRecordTypePolyBezierTo = EMR_POLYBEZIERTO,
+ EmfRecordTypePolyLineTo = EMR_POLYLINETO,
+ EmfRecordTypePolyPolyline = EMR_POLYPOLYLINE,
+ EmfRecordTypePolyPolygon = EMR_POLYPOLYGON,
+ EmfRecordTypeSetWindowExtEx = EMR_SETWINDOWEXTEX,
+ EmfRecordTypeSetWindowOrgEx = EMR_SETWINDOWORGEX,
+ EmfRecordTypeSetViewportExtEx = EMR_SETVIEWPORTEXTEX,
+ EmfRecordTypeSetViewportOrgEx = EMR_SETVIEWPORTORGEX,
+ EmfRecordTypeSetBrushOrgEx = EMR_SETBRUSHORGEX,
+ EmfRecordTypeEOF = EMR_EOF,
+ EmfRecordTypeSetPixelV = EMR_SETPIXELV,
+ EmfRecordTypeSetMapperFlags = EMR_SETMAPPERFLAGS,
+ EmfRecordTypeSetMapMode = EMR_SETMAPMODE,
+ EmfRecordTypeSetBkMode = EMR_SETBKMODE,
+ EmfRecordTypeSetPolyFillMode = EMR_SETPOLYFILLMODE,
+ EmfRecordTypeSetROP2 = EMR_SETROP2,
+ EmfRecordTypeSetStretchBltMode = EMR_SETSTRETCHBLTMODE,
+ EmfRecordTypeSetTextAlign = EMR_SETTEXTALIGN,
+ EmfRecordTypeSetColorAdjustment = EMR_SETCOLORADJUSTMENT,
+ EmfRecordTypeSetTextColor = EMR_SETTEXTCOLOR,
+ EmfRecordTypeSetBkColor = EMR_SETBKCOLOR,
+ EmfRecordTypeOffsetClipRgn = EMR_OFFSETCLIPRGN,
+ EmfRecordTypeMoveToEx = EMR_MOVETOEX,
+ EmfRecordTypeSetMetaRgn = EMR_SETMETARGN,
+ EmfRecordTypeExcludeClipRect = EMR_EXCLUDECLIPRECT,
+ EmfRecordTypeIntersectClipRect = EMR_INTERSECTCLIPRECT,
+ EmfRecordTypeScaleViewportExtEx = EMR_SCALEVIEWPORTEXTEX,
+ EmfRecordTypeScaleWindowExtEx = EMR_SCALEWINDOWEXTEX,
+ EmfRecordTypeSaveDC = EMR_SAVEDC,
+ EmfRecordTypeRestoreDC = EMR_RESTOREDC,
+ EmfRecordTypeSetWorldTransform = EMR_SETWORLDTRANSFORM,
+ EmfRecordTypeModifyWorldTransform = EMR_MODIFYWORLDTRANSFORM,
+ EmfRecordTypeSelectObject = EMR_SELECTOBJECT,
+ EmfRecordTypeCreatePen = EMR_CREATEPEN,
+ EmfRecordTypeCreateBrushIndirect = EMR_CREATEBRUSHINDIRECT,
+ EmfRecordTypeDeleteObject = EMR_DELETEOBJECT,
+ EmfRecordTypeAngleArc = EMR_ANGLEARC,
+ EmfRecordTypeEllipse = EMR_ELLIPSE,
+ EmfRecordTypeRectangle = EMR_RECTANGLE,
+ EmfRecordTypeRoundRect = EMR_ROUNDRECT,
+ EmfRecordTypeArc = EMR_ARC,
+ EmfRecordTypeChord = EMR_CHORD,
+ EmfRecordTypePie = EMR_PIE,
+ EmfRecordTypeSelectPalette = EMR_SELECTPALETTE,
+ EmfRecordTypeCreatePalette = EMR_CREATEPALETTE,
+ EmfRecordTypeSetPaletteEntries = EMR_SETPALETTEENTRIES,
+ EmfRecordTypeResizePalette = EMR_RESIZEPALETTE,
+ EmfRecordTypeRealizePalette = EMR_REALIZEPALETTE,
+ EmfRecordTypeExtFloodFill = EMR_EXTFLOODFILL,
+ EmfRecordTypeLineTo = EMR_LINETO,
+ EmfRecordTypeArcTo = EMR_ARCTO,
+ EmfRecordTypePolyDraw = EMR_POLYDRAW,
+ EmfRecordTypeSetArcDirection = EMR_SETARCDIRECTION,
+ EmfRecordTypeSetMiterLimit = EMR_SETMITERLIMIT,
+ EmfRecordTypeBeginPath = EMR_BEGINPATH,
+ EmfRecordTypeEndPath = EMR_ENDPATH,
+ EmfRecordTypeCloseFigure = EMR_CLOSEFIGURE,
+ EmfRecordTypeFillPath = EMR_FILLPATH,
+ EmfRecordTypeStrokeAndFillPath = EMR_STROKEANDFILLPATH,
+ EmfRecordTypeStrokePath = EMR_STROKEPATH,
+ EmfRecordTypeFlattenPath = EMR_FLATTENPATH,
+ EmfRecordTypeWidenPath = EMR_WIDENPATH,
+ EmfRecordTypeSelectClipPath = EMR_SELECTCLIPPATH,
+ EmfRecordTypeAbortPath = EMR_ABORTPATH,
+ EmfRecordTypeReserved_069 = 69, // Not Used
+ EmfRecordTypeGdiComment = EMR_GDICOMMENT,
+ EmfRecordTypeFillRgn = EMR_FILLRGN,
+ EmfRecordTypeFrameRgn = EMR_FRAMERGN,
+ EmfRecordTypeInvertRgn = EMR_INVERTRGN,
+ EmfRecordTypePaintRgn = EMR_PAINTRGN,
+ EmfRecordTypeExtSelectClipRgn = EMR_EXTSELECTCLIPRGN,
+ EmfRecordTypeBitBlt = EMR_BITBLT,
+ EmfRecordTypeStretchBlt = EMR_STRETCHBLT,
+ EmfRecordTypeMaskBlt = EMR_MASKBLT,
+ EmfRecordTypePlgBlt = EMR_PLGBLT,
+ EmfRecordTypeSetDIBitsToDevice = EMR_SETDIBITSTODEVICE,
+ EmfRecordTypeStretchDIBits = EMR_STRETCHDIBITS,
+ EmfRecordTypeExtCreateFontIndirect = EMR_EXTCREATEFONTINDIRECTW,
+ EmfRecordTypeExtTextOutA = EMR_EXTTEXTOUTA,
+ EmfRecordTypeExtTextOutW = EMR_EXTTEXTOUTW,
+ EmfRecordTypePolyBezier16 = EMR_POLYBEZIER16,
+ EmfRecordTypePolygon16 = EMR_POLYGON16,
+ EmfRecordTypePolyline16 = EMR_POLYLINE16,
+ EmfRecordTypePolyBezierTo16 = EMR_POLYBEZIERTO16,
+ EmfRecordTypePolylineTo16 = EMR_POLYLINETO16,
+ EmfRecordTypePolyPolyline16 = EMR_POLYPOLYLINE16,
+ EmfRecordTypePolyPolygon16 = EMR_POLYPOLYGON16,
+ EmfRecordTypePolyDraw16 = EMR_POLYDRAW16,
+ EmfRecordTypeCreateMonoBrush = EMR_CREATEMONOBRUSH,
+ EmfRecordTypeCreateDIBPatternBrushPt = EMR_CREATEDIBPATTERNBRUSHPT,
+ EmfRecordTypeExtCreatePen = EMR_EXTCREATEPEN,
+ EmfRecordTypePolyTextOutA = EMR_POLYTEXTOUTA,
+ EmfRecordTypePolyTextOutW = EMR_POLYTEXTOUTW,
+ EmfRecordTypeSetICMMode = 98, // EMR_SETICMMODE,
+ EmfRecordTypeCreateColorSpace = 99, // EMR_CREATECOLORSPACE,
+ EmfRecordTypeSetColorSpace = 100, // EMR_SETCOLORSPACE,
+ EmfRecordTypeDeleteColorSpace = 101, // EMR_DELETECOLORSPACE,
+ EmfRecordTypeGLSRecord = 102, // EMR_GLSRECORD,
+ EmfRecordTypeGLSBoundedRecord = 103, // EMR_GLSBOUNDEDRECORD,
+ EmfRecordTypePixelFormat = 104, // EMR_PIXELFORMAT,
+ EmfRecordTypeDrawEscape = 105, // EMR_RESERVED_105,
+ EmfRecordTypeExtEscape = 106, // EMR_RESERVED_106,
+ EmfRecordTypeStartDoc = 107, // EMR_RESERVED_107,
+ EmfRecordTypeSmallTextOut = 108, // EMR_RESERVED_108,
+ EmfRecordTypeForceUFIMapping = 109, // EMR_RESERVED_109,
+ EmfRecordTypeNamedEscape = 110, // EMR_RESERVED_110,
+ EmfRecordTypeColorCorrectPalette = 111, // EMR_COLORCORRECTPALETTE,
+ EmfRecordTypeSetICMProfileA = 112, // EMR_SETICMPROFILEA,
+ EmfRecordTypeSetICMProfileW = 113, // EMR_SETICMPROFILEW,
+ EmfRecordTypeAlphaBlend = 114, // EMR_ALPHABLEND,
+ EmfRecordTypeSetLayout = 115, // EMR_SETLAYOUT,
+ EmfRecordTypeTransparentBlt = 116, // EMR_TRANSPARENTBLT,
+ EmfRecordTypeReserved_117 = 117, // Not Used
+ EmfRecordTypeGradientFill = 118, // EMR_GRADIENTFILL,
+ EmfRecordTypeSetLinkedUFIs = 119, // EMR_RESERVED_119,
+ EmfRecordTypeSetTextJustification = 120, // EMR_RESERVED_120,
+ EmfRecordTypeColorMatchToTargetW = 121, // EMR_COLORMATCHTOTARGETW,
+ EmfRecordTypeCreateColorSpaceW = 122, // EMR_CREATECOLORSPACEW,
+ EmfRecordTypeMax = 122,
+ EmfRecordTypeMin = 1,
+
+ // That is the END of the GDI EMF records.
+
+ // Now we start the list of EMF+ records. We leave quite
+ // a bit of room here for the addition of any new GDI
+ // records that may be added later.
+
+ EmfPlusRecordTypeInvalid = GDIP_EMFPLUS_RECORD_BASE,
+ EmfPlusRecordTypeHeader,
+ EmfPlusRecordTypeEndOfFile,
+
+ EmfPlusRecordTypeComment,
+
+ EmfPlusRecordTypeGetDC, // the application grabbed the metafile dc
+
+ EmfPlusRecordTypeMultiFormatStart,
+ EmfPlusRecordTypeMultiFormatSection,
+ EmfPlusRecordTypeMultiFormatEnd,
+
+ // For all persistent objects
+ EmfPlusRecordTypeObject, // brush,pen,path,region,image,font,string-format
+
+ // Drawing Records
+ EmfPlusRecordTypeClear,
+ EmfPlusRecordTypeFillRects,
+ EmfPlusRecordTypeDrawRects,
+ EmfPlusRecordTypeFillPolygon,
+ EmfPlusRecordTypeDrawLines,
+ EmfPlusRecordTypeFillEllipse,
+ EmfPlusRecordTypeDrawEllipse,
+ EmfPlusRecordTypeFillPie,
+ EmfPlusRecordTypeDrawPie,
+ EmfPlusRecordTypeDrawArc,
+ EmfPlusRecordTypeFillRegion,
+ EmfPlusRecordTypeFillPath,
+ EmfPlusRecordTypeDrawPath,
+ EmfPlusRecordTypeFillClosedCurve,
+ EmfPlusRecordTypeDrawClosedCurve,
+ EmfPlusRecordTypeDrawCurve,
+ EmfPlusRecordTypeDrawBeziers,
+ EmfPlusRecordTypeDrawImage,
+ EmfPlusRecordTypeDrawImagePoints,
+ EmfPlusRecordTypeDrawString,
+
+ // Graphics State Records
+ EmfPlusRecordTypeSetRenderingOrigin,
+ EmfPlusRecordTypeSetAntiAliasMode,
+ EmfPlusRecordTypeSetTextRenderingHint,
+#ifdef DCR_USE_NEW_188922
+ EmfPlusRecordTypeSetTextContrast,
+#else
+ EmfPlusRecordTypeSetGammaValue,
+#endif // DCR_USE_NEW_188922
+ EmfPlusRecordTypeSetInterpolationMode,
+ EmfPlusRecordTypeSetPixelOffsetMode,
+ EmfPlusRecordTypeSetCompositingMode,
+ EmfPlusRecordTypeSetCompositingQuality,
+ EmfPlusRecordTypeSave,
+ EmfPlusRecordTypeRestore,
+ EmfPlusRecordTypeBeginContainer,
+ EmfPlusRecordTypeBeginContainerNoParams,
+ EmfPlusRecordTypeEndContainer,
+ EmfPlusRecordTypeSetWorldTransform,
+ EmfPlusRecordTypeResetWorldTransform,
+ EmfPlusRecordTypeMultiplyWorldTransform,
+ EmfPlusRecordTypeTranslateWorldTransform,
+ EmfPlusRecordTypeScaleWorldTransform,
+ EmfPlusRecordTypeRotateWorldTransform,
+ EmfPlusRecordTypeSetPageTransform,
+ EmfPlusRecordTypeResetClip,
+ EmfPlusRecordTypeSetClipRect,
+ EmfPlusRecordTypeSetClipPath,
+ EmfPlusRecordTypeSetClipRegion,
+ EmfPlusRecordTypeOffsetClip,
+
+ // New record types must be added here (at the end) -- do not add above,
+ // since that will invalidate previous metafiles!
+ EmfPlusRecordTypeDrawDriverString,
+
+ // Have this here so you don't need to keep changing the value of
+ // EmfPlusRecordTypeMax every time you add a new record.
+
+ EmfPlusRecordTotal,
+
+ EmfPlusRecordTypeMax = EmfPlusRecordTotal-1,
+ EmfPlusRecordTypeMin = EmfPlusRecordTypeHeader,
+};
+
+//---------------------------------------------------------------------------
+// StringFormatFlags
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// String format flags
+//
+// DirectionRightToLeft - For horizontal text, the reading order is
+// right to left. This value is called
+// the base embedding level by the Unicode
+// bidirectional engine.
+// For vertical text, columns are read from
+// right to left.
+// By default, horizontal or vertical text is
+// read from left to right.
+//
+// DirectionVertical - Individual lines of text are vertical. In
+// each line, characters progress from top to
+// bottom.
+// By default, lines of text are horizontal,
+// each new line below the previous line.
+//
+// NoFitBlackBox - Allows parts of glyphs to overhang the
+// bounding rectangle.
+// By default glyphs are first aligned
+// inside the margines, then any glyphs which
+// still overhang the bounding box are
+// repositioned to avoid any overhang.
+// For example when an italic
+// lower case letter f in a font such as
+// Garamond is aligned at the far left of a
+// rectangle, the lower part of the f will
+// reach slightly further left than the left
+// edge of the rectangle. Setting this flag
+// will ensure the character aligns visually
+// with the lines above and below, but may
+// cause some pixels outside the formatting
+// rectangle to be clipped or painted.
+//
+#ifndef DCR_USE_NEW_137252
+// NumberContextArabic - Causes any initial numeric in the string to
+// be analysed for bidirection layout as if
+// it was preceeded by Arabic text.
+//
+// DisableKashidaJustification - Arabic text will not be justified by the
+// insertion of kashidas (i.e. extending the
+// joining line between characters). Instead
+// Arabic script will be justified by the
+// widening of the whitespace between words.
+//
+#endif
+// DisplayFormatControl - Causes control characters such as the
+// left-to-right mark to be shown in the
+// output with a representative glyph.
+//
+#ifndef DCR_USE_NEW_137252
+// DisableKerning - Disables Truetype and OpenType kerning.
+//
+// DisableLigatures - Disables Truetype and OpenType ligatures.
+//
+// LayoutLegacyBidi - Causes the bidirection algorithm to use
+// slightly different classifications for
+// '+', '-' and '/' that make their layout
+// much closer to that expected by files
+// generated in Windows or by Windows
+// applications.
+//
+// NoChanges - A text imager created with this flag set
+// does not support those APIs that change
+// it's contents or formatting, but for most
+// simple text will be significantly faster in
+// performing measurement and drawing
+// functions.
+//
+#endif
+// NoFontFallback - Disables fallback to alternate fonts for
+// characters not supported in the requested
+// font. Any missing characters will be
+// be displayed with the fonts missing glyph,
+// usually an open square.
+//
+// NoWrap - Disables wrapping of text between lines
+// when formatting within a rectangle.
+// NoWrap is implied when a point is passed
+// instead of a rectangle, or when the
+// specified rectangle has a zero line length.
+//
+// NoClip - By default text is clipped to the
+// formatting rectangle. Setting NoClip
+// allows overhanging pixels to affect the
+// device outside the formatting rectangle.
+// Pixels at the end of the line may be
+// affected if the glyphs overhang their
+// cells, and either the NoFitBlackBox flag
+// has been set, or the glyph extends to far
+// to be fitted.
+// Pixels above/before the first line or
+// below/after the last line may be affected
+// if the glyphs extend beyond their cell
+// ascent / descent. This can occur rarely
+// with unusual diacritic mark combinations.
+
+//---------------------------------------------------------------------------
+
+enum StringFormatFlags
+{
+ StringFormatFlagsDirectionRightToLeft = 0x00000001,
+ StringFormatFlagsDirectionVertical = 0x00000002,
+ StringFormatFlagsNoFitBlackBox = 0x00000004,
+#ifndef DCR_USE_NEW_137252
+ StringFormatFlagsNumberContextArabic = 0x00000008,
+ StringFormatFlagsDisableKashidaJustification = 0x00000010,
+#endif
+ StringFormatFlagsDisplayFormatControl = 0x00000020,
+#ifndef DCR_USE_NEW_137252
+ StringFormatFlagsDisableKerning = 0x00000040,
+ StringFormatFlagsDisableLigatures = 0x00000080,
+ StringFormatFlagsLayoutLegacyBidi = 0x00000100,
+ StringFormatFlagsNoChanges = 0x00000200,
+#endif
+ StringFormatFlagsNoFontFallback = 0x00000400,
+ StringFormatFlagsMeasureTrailingSpaces = 0x00000800,
+ StringFormatFlagsNoWrap = 0x00001000,
+ StringFormatFlagsLineLimit = 0x00002000,
+
+ StringFormatFlagsNoClip = 0x00004000
+};
+
+//---------------------------------------------------------------------------
+// StringTrimming
+//---------------------------------------------------------------------------
+
+enum StringTrimming {
+ StringTrimmingNone = 0,
+ StringTrimmingCharacter = 1,
+ StringTrimmingWord = 2,
+ StringTrimmingEllipsisCharacter = 3,
+ StringTrimmingEllipsisWord = 4,
+ StringTrimmingEllipsisPath = 5
+};
+
+#ifndef DCR_USE_NEW_137252
+//---------------------------------------------------------------------------
+// String units
+//
+// String units are like length units in CSS, they may be absolute, or
+// they may be relative to a font size.
+//
+//---------------------------------------------------------------------------
+
+enum StringUnit {
+ StringUnitWorld = UnitWorld,
+ StringUnitDisplay = UnitDisplay,
+ StringUnitPixel = UnitPixel,
+ StringUnitPoint = UnitPoint,
+ StringUnitInch = UnitInch,
+ StringUnitDocument = UnitDocument,
+ StringUnitMillimeter = UnitMillimeter,
+ StringUnitEm = 32
+};
+#endif
+
+#ifndef DCR_USE_NEW_152154
+//---------------------------------------------------------------------------
+// Line spacing flags
+//---------------------------------------------------------------------------
+
+enum LineSpacing {
+ LineSpacingWorld = UnitWorld,
+ LineSpacingDisplay = UnitDisplay,
+ LineSpacingPixel = UnitPixel,
+ LineSpacingPoint = UnitPoint,
+ LineSpacingInch = UnitInch,
+ LineSpacingDocument = UnitDocument,
+ LineSpacingMillimeter = UnitMillimeter,
+
+ LineSpacingRecommended = 32,
+ LineSpacingAtLeast = 33,
+ LineSpacingAtLeastMultiple = 34,
+ LineSpacingCell = 35,
+ LineSpacingCellAtLeast = 36,
+ LineSpacingCellAtLeastMultiple = 37
+};
+
+/// The following methods of linespacing are relative to the font size
+//
+// =========== Method =========== =============== Relative to ===============
+//
+// LineSpacingRecommended recommended line spacing specified by font
+// LineSpacingAtLeast max(recommended, tallest glyph cell)
+// LineSpacingAtLeastMultiple smallest multiple of recommended big enough
+// for all glyph cells on the line
+// LineSpacingCell cell height
+// LineSpacingCellAtLeast max(font cell height, tallest glyph cell)
+// LineSpacingCellAtLeastMultiple smallest multiple of cell height big enough
+// for all glyph cells on the line
+#endif
+
+
+//---------------------------------------------------------------------------
+// National language digit substitution
+//---------------------------------------------------------------------------
+
+enum StringDigitSubstitute
+{
+ StringDigitSubstituteUser = 0, // As NLS setting
+ StringDigitSubstituteNone = 1,
+ StringDigitSubstituteNational = 2,
+ StringDigitSubstituteTraditional = 3
+};
+
+//---------------------------------------------------------------------------
+// Hotkey prefix interpretation
+//---------------------------------------------------------------------------
+
+enum HotkeyPrefix
+{
+ HotkeyPrefixNone = 0,
+ HotkeyPrefixShow = 1,
+ HotkeyPrefixHide = 2
+};
+
+//---------------------------------------------------------------------------
+// Text alignment flags
+//---------------------------------------------------------------------------
+
+enum StringAlignment
+{
+ // Left edge for left-to-right text,
+ // right for right-to-left text,
+ // and top for vertical
+ StringAlignmentNear = 0,
+ StringAlignmentCenter = 1,
+ StringAlignmentFar = 2
+};
+
+//---------------------------------------------------------------------------
+// DriverStringOptions
+//---------------------------------------------------------------------------
+
+enum DriverStringOptions
+{
+ DriverStringOptionsCmapLookup = 1,
+ DriverStringOptionsVertical = 2,
+ DriverStringOptionsRealizedAdvance = 4,
+#ifndef DCR_USE_NEW_137252
+ DriverStringOptionsCompensateResolution = 8
+#endif
+};
+
+//---------------------------------------------------------------------------
+// Flush Intention flags
+//---------------------------------------------------------------------------
+
+enum FlushIntention
+{
+ FlushIntentionFlush = 0, // Flush all batched rendering operations
+ FlushIntentionSync = 1 // Flush all batched rendering operations
+ // and wait for them to complete
+};
+
+#ifndef DCR_USE_NEW_175866
+
+//---------------------------------------------------------------------------
+// Window Change Notification types
+//---------------------------------------------------------------------------
+
+enum WindowNotifyEnum
+{
+ WindowNotifyEnumEnable = 0,
+ WindowNotifyEnumDisable,
+ WindowNotifyEnumPalette,
+ WindowNotifyEnumDisplay,
+ WindowNotifyEnumSysColor
+};
+
+#endif
+
+//---------------------------------------------------------------------------
+// Image encoder parameter related types
+//---------------------------------------------------------------------------
+
+#ifdef DCR_USE_NEW_145804
+enum EncoderParameterValueType
+{
+ EncoderParameterValueTypeByte = 1, // 8-bit unsigned int
+ EncoderParameterValueTypeASCII = 2, // 8-bit byte containing one 7-bit ASCII
+ // code. NULL terminated.
+ EncoderParameterValueTypeShort = 3, // 16-bit unsigned int
+ EncoderParameterValueTypeLong = 4, // 32-bit unsigned int
+ EncoderParameterValueTypeRational = 5, // Two Longs. The first Long is the
+ // numerator, the second Long expresses the
+ // denomintor.
+ EncoderParameterValueTypeLongRange = 6, // Two longs which specify a range of
+ // integer values. The first Long specifies
+ // the lower end and the second one
+ // specifies the higher end. All values
+ // are inclusive at both ends
+ EncoderParameterValueTypeUndefined = 7, // 8-bit byte that can take any value
+ // depending on field definition
+ EncoderParameterValueTypeRationalRange = 8 // Two Rationals. The first Rational
+ // specifies the lower end and the second
+ // specifies the higher end. All values
+ // are inclusive at both ends
+};
+#else
+enum ValueType
+{
+ ValueTypeByte = 1, // 8-bit unsigned int
+ ValueTypeASCII = 2, // 8-bit byte containing one 7-bit ASCII
+ // code. NULL terminated.
+ ValueTypeShort = 3, // 16-bit unsigned int
+ ValueTypeLong = 4, // 32-bit unsigned int
+ ValueTypeRational = 5, // Two Longs. The first Long is the
+ // numerator, the second Long expresses the
+ // denomintor.
+ ValueTypeLongRange = 6, // Two longs which specify a range of
+ // integer values. The first Long specifies
+ // the lower end and the second one
+ // specifies the higher end. All values
+ // are inclusive at both ends
+ ValueTypeUndefined = 7, // 8-bit byte that can take any value
+ // depending on field definition
+ ValueTypeRationalRange = 8 // Two Rationals. The first Rational
+ // specifies the lower end and the second
+ // specifies the higher end. All values
+ // are inclusive at both ends
+};
+#endif
+
+//---------------------------------------------------------------------------
+// Image encoder value types
+//---------------------------------------------------------------------------
+
+enum EncoderValue
+{
+ EncoderValueColorTypeCMYK,
+ EncoderValueColorTypeYCCK,
+ EncoderValueCompressionLZW,
+ EncoderValueCompressionCCITT3,
+ EncoderValueCompressionCCITT4,
+ EncoderValueCompressionRle,
+ EncoderValueCompressionNone,
+ EncoderValueScanMethodInterlaced,
+ EncoderValueScanMethodNonInterlaced,
+ EncoderValueVersionGif87,
+ EncoderValueVersionGif89,
+ EncoderValueRenderProgressive,
+ EncoderValueRenderNonProgressive,
+ EncoderValueTransformRotate90,
+ EncoderValueTransformRotate180,
+ EncoderValueTransformRotate270,
+ EncoderValueTransformFlipHorizontal,
+ EncoderValueTransformFlipVertical,
+ #ifdef DCR_USE_NEW_140861
+ EncoderValueMultiFrame,
+ #else
+ EncodeValueMultiFrame,
+ #endif
+ EncoderValueLastFrame,
+ EncoderValueFlush,
+ #ifdef DCR_USE_NEW_140861
+ EncoderValueFrameDimensionTime,
+ EncoderValueFrameDimensionResolution,
+ EncoderValueFrameDimensionPage
+ #else
+ EncodeValueFrameDimensionTime,
+ EncodeValueFrameDimensionResolution,
+ EncodeValueFrameDimensionPage
+ #endif
+};
+
+//---------------------------------------------------------------------------
+// Graphics layout values (support for Middle East localization)
+//---------------------------------------------------------------------------
+
+enum GraphicsLayout
+{
+ GraphicsLayoutNormal,
+ GraphicsLayoutMirrored,
+ GraphicsLayoutMirroredIgnoreImages,
+ GraphicsLayoutMirroredForceImages
+};
+
+//---------------------------------------------------------------------------
+// Image layout values (support for Middle East localization)
+//---------------------------------------------------------------------------
+
+enum ImageLayout
+{
+ ImageLayoutNormal,
+ ImageLayoutIgnoreMirrored
+};
+
+enum EmfToWmfBitsFlags
+{
+ EmfToWmfBitsFlagsDefault = 0x00000000,
+ EmfToWmfBitsFlagsEmbedEmf = 0x00000001,
+ EmfToWmfBitsFlagsIncludeAPM = 0x00000002,
+ EmfToWmfBitsFlagsNoXORClip = 0x00000004
+};
+
+#endif // !_GDIPLUSENUMS_H
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusFlat.h b/core/src/fxge/Microsoft SDK/include/GdiPlusFlat.h
index 8b5369e793..1dd8d466e9 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusFlat.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusFlat.h
@@ -1,2740 +1,2740 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusFlat.h
-*
-* Abstract:
-*
-* Flat GDI+ API wrappers - header file
-*
-\**************************************************************************/
-
-// TODO: this file style needs to be made internally consistent with the way
-// it handles breaking the long argument lists across multiple lines
-
-#ifndef _FLATAPI_H
-#define _FLATAPI_H
-
-#define WINGDIPAPI __stdcall
-
-// currently, only C++ wrapper API's force const.
-
-#define GDIPCONST const
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef DCR_USE_NEW_175866
-
-VOID
-WINGDIPAPI
-GdipDisplayPaletteWindowNotify(WindowNotifyEnum notify);
-
-#endif
-
-//----------------------------------------------------------------------------
-// GraphicsPath methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreatePath(GpFillMode brushMode, GpPath **path);
-
-GpStatus WINGDIPAPI
-GdipCreatePath2(GDIPCONST GpPointF*, GDIPCONST BYTE*, INT, GpFillMode,
- GpPath **path);
-
-GpStatus WINGDIPAPI
-GdipCreatePath2I(GDIPCONST GpPoint*, GDIPCONST BYTE*, INT, GpFillMode,
- GpPath **path);
-
-GpStatus WINGDIPAPI
-GdipClonePath(GpPath* path, GpPath **clonePath);
-
-GpStatus WINGDIPAPI
-GdipDeletePath(GpPath* path);
-
-GpStatus WINGDIPAPI
-GdipResetPath(GpPath* path);
-
-GpStatus WINGDIPAPI
-GdipGetPointCount(GpPath* path, INT* count);
-
-GpStatus WINGDIPAPI
-GdipGetPathTypes(GpPath* path, BYTE* types, INT count);
-
-GpStatus WINGDIPAPI
-GdipGetPathPoints(GpPath*, GpPointF* points, INT count);
-
-GpStatus WINGDIPAPI
-GdipGetPathPointsI(GpPath*, GpPoint* points, INT count);
-
-GpStatus WINGDIPAPI
-GdipGetPathFillMode(GpPath *path, GpFillMode *fillmode);
-
-GpStatus WINGDIPAPI
-GdipSetPathFillMode(GpPath *path, GpFillMode fillmode);
-
-GpStatus WINGDIPAPI
-GdipGetPathData(GpPath *path, GpPathData* pathData);
-
-GpStatus WINGDIPAPI
-GdipStartPathFigure(GpPath *path);
-
-GpStatus WINGDIPAPI
-GdipClosePathFigure(GpPath *path);
-
-GpStatus WINGDIPAPI
-GdipClosePathFigures(GpPath *path);
-
-GpStatus WINGDIPAPI
-GdipSetPathMarker(GpPath* path);
-
-GpStatus WINGDIPAPI
-GdipClearPathMarkers(GpPath* path);
-
-GpStatus WINGDIPAPI
-GdipReversePath(GpPath* path);
-
-GpStatus WINGDIPAPI
-GdipGetPathLastPoint(GpPath* path, GpPointF* lastPoint);
-
-GpStatus WINGDIPAPI
-GdipAddPathLine(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2);
-
-GpStatus WINGDIPAPI
-GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathArc(GpPath *path, REAL x, REAL y, REAL width, REAL height,
- REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2,
- REAL x3, REAL y3, REAL x4, REAL y4);
-
-GpStatus WINGDIPAPI
-GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathCurve(GpPath *path, GDIPCONST GpPointF *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count,
- REAL tension);
-
-GpStatus WINGDIPAPI
-GdipAddPathCurve3(GpPath *path, GDIPCONST GpPointF *points, INT count,
- INT offset, INT numberOfSegments, REAL tension);
-
-GpStatus WINGDIPAPI
-GdipAddPathClosedCurve(GpPath *path, GDIPCONST GpPointF *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count,
- REAL tension);
-
-GpStatus WINGDIPAPI
-GdipAddPathRectangle(GpPath *path, REAL x, REAL y, REAL width, REAL height);
-
-GpStatus WINGDIPAPI
-GdipAddPathRectangles(GpPath *path, GDIPCONST GpRectF *rects, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathEllipse(GpPath *path, REAL x, REAL y, REAL width,
- REAL height);
-
-GpStatus WINGDIPAPI
-GdipAddPathPie(GpPath *path, REAL x, REAL y, REAL width, REAL height,
- REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipAddPathPolygon(GpPath *path, GDIPCONST GpPointF *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathPath(GpPath *path, GDIPCONST GpPath* addingPath, BOOL connect);
-
-GpStatus WINGDIPAPI
-GdipAddPathString(GpPath *path, GDIPCONST WCHAR *string,
- INT length, GDIPCONST GpFontFamily *family, INT style,
- REAL emSize, GDIPCONST RectF *layoutRect,
- GDIPCONST GpStringFormat *format);
-
-GpStatus WINGDIPAPI
-GdipAddPathStringI(GpPath *path, GDIPCONST WCHAR *string,
- INT length, GDIPCONST GpFontFamily *family, INT style,
- REAL emSize, GDIPCONST Rect *layoutRect,
- GDIPCONST GpStringFormat *format);
-
-GpStatus WINGDIPAPI
-GdipAddPathLineI(GpPath *path, INT x1, INT y1, INT x2, INT y2);
-
-GpStatus WINGDIPAPI
-GdipAddPathLine2I(GpPath *path, GDIPCONST GpPoint *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathArcI(GpPath *path, INT x, INT y, INT width, INT height,
- REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipAddPathBezierI(GpPath *path, INT x1, INT y1, INT x2, INT y2,
- INT x3, INT y3, INT x4, INT y4);
-
-GpStatus WINGDIPAPI
-GdipAddPathBeziersI(GpPath *path, GDIPCONST GpPoint *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathCurveI(GpPath *path, GDIPCONST GpPoint *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathCurve2I(GpPath *path, GDIPCONST GpPoint *points, INT count,
- REAL tension);
-
-GpStatus WINGDIPAPI
-GdipAddPathCurve3I(GpPath *path, GDIPCONST GpPoint *points, INT count,
- INT offset, INT numberOfSegments, REAL tension);
-
-GpStatus WINGDIPAPI
-GdipAddPathClosedCurveI(GpPath *path, GDIPCONST GpPoint *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathClosedCurve2I(GpPath *path, GDIPCONST GpPoint *points, INT count,
- REAL tension);
-
-GpStatus WINGDIPAPI
-GdipAddPathRectangleI(GpPath *path, INT x, INT y, INT width, INT height);
-
-GpStatus WINGDIPAPI
-GdipAddPathRectanglesI(GpPath *path, GDIPCONST GpRect *rects, INT count);
-
-GpStatus WINGDIPAPI
-GdipAddPathEllipseI(GpPath *path, INT x, INT y, INT width, INT height);
-
-GpStatus WINGDIPAPI
-GdipAddPathPieI(GpPath *path, INT x, INT y, INT width, INT height,
- REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipAddPathPolygonI(GpPath *path, GDIPCONST GpPoint *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipFlattenPath(GpPath *path, GpMatrix* matrix, REAL flatness);
-
-GpStatus WINGDIPAPI
-GdipWindingModeOutline(
- GpPath *path,
- GpMatrix *matrix,
- REAL flatness
-);
-
-
-#ifdef DCR_USE_NEW_202903
-
-GpStatus WINGDIPAPI
-GdipWidenPath(
- GpPath *nativePath,
- GpPen *pen,
- GpMatrix *matrix,
- REAL flatness
-);
-
-#else
-
-GpStatus WINGDIPAPI
-GdipWidenPathWithMinimumResolutions(GpPath *path, GpPen *pen, REAL minXres,
- REAL minYres, GpMatrix *matrix, BOOL removeSelftIntersects);
-
-#endif
-
-GpStatus WINGDIPAPI
-GdipWarpPath(GpPath *path, GpMatrix* matrix,
- GDIPCONST GpPointF *points, INT count,
- REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight,
- WarpMode warpMode, REAL flatness);
-
-GpStatus WINGDIPAPI
-GdipTransformPath(GpPath* path, GpMatrix* matrix);
-
-GpStatus WINGDIPAPI
-GdipGetPathWorldBounds(GpPath* path, GpRectF* bounds, GDIPCONST GpMatrix *matrix,
- GDIPCONST GpPen *pen);
-
-GpStatus WINGDIPAPI
-GdipGetPathWorldBoundsI(GpPath* path, GpRect* bounds, GDIPCONST GpMatrix *matrix,
- GDIPCONST GpPen *pen);
-
-GpStatus WINGDIPAPI
-GdipIsVisiblePathPoint(GpPath* path, REAL x, REAL y,
- GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsVisiblePathPointI(GpPath* path, INT x, INT y,
- GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsOutlineVisiblePathPoint(GpPath* path, REAL x, REAL y, GpPen *pen,
- GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsOutlineVisiblePathPointI(GpPath* path, INT x, INT y, GpPen *pen,
- GpGraphics *graphics, BOOL *result);
-
-
-//----------------------------------------------------------------------------
-// Path Enumeration methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreatePathIter(GpPathIterator **iterator, GpPath* path);
-
-GpStatus WINGDIPAPI
-GdipDeletePathIter(GpPathIterator *iterator);
-
-GpStatus WINGDIPAPI
-GdipPathIterNextSubpath(GpPathIterator* iterator, INT *resultCount,
- INT* startIndex, INT* endIndex, BOOL* isClosed);
-
-GpStatus WINGDIPAPI
-GdipPathIterNextSubpathPath(GpPathIterator* iterator, INT* resultCount,
- GpPath* path, BOOL* isClosed);
-
-GpStatus WINGDIPAPI
-GdipPathIterNextPathType(GpPathIterator* iterator, INT* resultCount,
- BYTE* pathType, INT* startIndex, INT* endIndex);
-
-GpStatus WINGDIPAPI
-GdipPathIterNextMarker(GpPathIterator* iterator, INT *resultCount,
- INT* startIndex, INT* endIndex);
-
-GpStatus WINGDIPAPI
-GdipPathIterNextMarkerPath(GpPathIterator* iterator, INT* resultCount,
- GpPath* path);
-
-GpStatus WINGDIPAPI
-GdipPathIterGetCount(GpPathIterator* iterator, INT* count);
-
-GpStatus WINGDIPAPI
-GdipPathIterGetSubpathCount(GpPathIterator* iterator, INT* count);
-
-GpStatus WINGDIPAPI
-GdipPathIterIsValid(GpPathIterator* iterator, BOOL* valid);
-
-GpStatus WINGDIPAPI
-GdipPathIterHasCurve(GpPathIterator* iterator, BOOL* hasCurve);
-
-GpStatus WINGDIPAPI
-GdipPathIterRewind(GpPathIterator* iterator);
-
-GpStatus WINGDIPAPI
-GdipPathIterEnumerate(GpPathIterator* iterator, INT* resultCount,
- GpPointF *points, BYTE *types, INT count);
-
-GpStatus WINGDIPAPI
-GdipPathIterCopyData(GpPathIterator* iterator, INT* resultCount,
- GpPointF* points, BYTE* types, INT startIndex, INT endIndex);
-
-//----------------------------------------------------------------------------
-// Matrix methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateMatrix(GpMatrix **matrix);
-
-GpStatus WINGDIPAPI
-GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx,
- REAL dy, GpMatrix **matrix);
-
-GpStatus WINGDIPAPI
-GdipCreateMatrix3(GDIPCONST GpRectF *rect, GDIPCONST GpPointF *dstplg,
- GpMatrix **matrix);
-
-GpStatus WINGDIPAPI
-GdipCreateMatrix3I(GDIPCONST GpRect *rect, GDIPCONST GpPoint *dstplg,
- GpMatrix **matrix);
-
-GpStatus WINGDIPAPI
-GdipCloneMatrix(GpMatrix *matrix, GpMatrix **cloneMatrix);
-
-GpStatus WINGDIPAPI
-GdipDeleteMatrix(GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12, REAL m21, REAL m22,
- REAL dx, REAL dy);
-
-GpStatus WINGDIPAPI
-GdipMultiplyMatrix(GpMatrix *matrix, GpMatrix* matrix2,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipTranslateMatrix(GpMatrix *matrix, REAL offsetX, REAL offsetY,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipRotateMatrix(GpMatrix *matrix, REAL angle, GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipInvertMatrix(GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count);
-
-GpStatus WINGDIPAPI
-GdipTransformMatrixPointsI(GpMatrix *matrix, GpPoint *pts, INT count);
-
-GpStatus WINGDIPAPI
-GdipVectorTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipVectorTransformMatrixPointsI(GpMatrix *matrix, GpPoint *pts,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipGetMatrixElements(GDIPCONST GpMatrix *matrix, REAL *matrixOut);
-
-GpStatus WINGDIPAPI
-GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsMatrixIdentity(GDIPCONST GpMatrix *matrix, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsMatrixEqual(GDIPCONST GpMatrix *matrix, GDIPCONST GpMatrix *matrix2, BOOL *result);
-
-//----------------------------------------------------------------------------
-// Region methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateRegion(GpRegion **region);
-
-GpStatus WINGDIPAPI
-GdipCreateRegionRect(GDIPCONST GpRectF *rect, GpRegion **region);
-
-GpStatus WINGDIPAPI
-GdipCreateRegionRectI(GDIPCONST GpRect *rect, GpRegion **region);
-
-GpStatus WINGDIPAPI
-GdipCreateRegionPath(GpPath *path, GpRegion **region);
-
-GpStatus WINGDIPAPI
-GdipCreateRegionRgnData(GDIPCONST BYTE *regionData, INT size, GpRegion **region);
-
-GpStatus WINGDIPAPI
-GdipCreateRegionHrgn(HRGN hRgn, GpRegion **region);
-
-GpStatus WINGDIPAPI
-GdipCloneRegion(GpRegion *region, GpRegion **cloneRegion);
-
-GpStatus WINGDIPAPI
-GdipDeleteRegion(GpRegion *region);
-
-GpStatus WINGDIPAPI
-GdipSetInfinite(GpRegion *region);
-
-GpStatus WINGDIPAPI
-GdipSetEmpty(GpRegion *region);
-
-GpStatus WINGDIPAPI
-GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect,
- CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipCombineRegionRectI(GpRegion *region, GDIPCONST GpRect *rect,
- CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipCombineRegionPath(GpRegion *region, GpPath *path, CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipCombineRegionRegion(GpRegion *region, GpRegion *region2,
- CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipTranslateRegion(GpRegion *region, REAL dx, REAL dy);
-
-GpStatus WINGDIPAPI
-GdipTranslateRegionI(GpRegion *region, INT dx, INT dy);
-
-GpStatus WINGDIPAPI
-GdipTransformRegion(GpRegion *region, GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics,
- GpRectF *rect);
-
-GpStatus WINGDIPAPI
-GdipGetRegionBoundsI(GpRegion *region, GpGraphics *graphics,
- GpRect *rect);
-
-GpStatus WINGDIPAPI
-GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN *hRgn);
-
-GpStatus WINGDIPAPI
-GdipIsEmptyRegion(GpRegion *region, GpGraphics *graphics,
- BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsInfiniteRegion(GpRegion *region, GpGraphics *graphics,
- BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsEqualRegion(GpRegion *region, GpRegion *region2,
- GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipGetRegionDataSize(GpRegion *region, UINT * bufferSize);
-
-GpStatus WINGDIPAPI
-GdipGetRegionData(GpRegion *region, BYTE * buffer, UINT bufferSize, UINT * sizeFilled);
-
-GpStatus WINGDIPAPI
-GdipIsVisibleRegionPoint(GpRegion *region, REAL x, REAL y,
- GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsVisibleRegionPointI(GpRegion *region, INT x, INT y,
- GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsVisibleRegionRect(GpRegion *region, REAL x, REAL y, REAL width,
- REAL height, GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsVisibleRegionRectI(GpRegion *region, INT x, INT y, INT width,
- INT height, GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipGetRegionScansCount(GpRegion *region, UINT* count, GpMatrix* matrix);
-
-GpStatus WINGDIPAPI
-GdipGetRegionScans(GpRegion *region, GpRectF* rects, INT* count, GpMatrix* matrix);
-
-GpStatus WINGDIPAPI
-GdipGetRegionScansI(GpRegion *region, GpRect* rects, INT* count, GpMatrix* matrix);
-
-//----------------------------------------------------------------------------
-// Brush methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCloneBrush(GpBrush *brush, GpBrush **cloneBrush);
-
-GpStatus WINGDIPAPI
-GdipDeleteBrush(GpBrush *brush);
-
-GpStatus WINGDIPAPI
-GdipGetBrushType(GpBrush *brush, GpBrushType *type);
-
-//----------------------------------------------------------------------------
-// Hatch Brush methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateHatchBrush(GpHatchStyle hatchstyle, ARGB forecol,
- ARGB backcol, GpHatch **brush);
-
-GpStatus WINGDIPAPI
-GdipGetHatchStyle(GpHatch *brush, GpHatchStyle *hatchstyle);
-
-GpStatus WINGDIPAPI
-GdipGetHatchForegroundColor(GpHatch *brush, ARGB* forecol);
-
-GpStatus WINGDIPAPI
-GdipGetHatchBackgroundColor(GpHatch *brush, ARGB* backcol);
-
-//----------------------------------------------------------------------------
-// Texture Brush methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateTexture(GpImage *image, GpWrapMode wrapmode,
- GpTexture **texture);
-
-GpStatus WINGDIPAPI
-GdipCreateTexture2(GpImage *image, GpWrapMode wrapmode, REAL x,
- REAL y, REAL width, REAL height, GpTexture **texture);
-
-GpStatus WINGDIPAPI
-GdipCreateTextureIA(GpImage *image, GDIPCONST GpImageAttributes *imageAttributes,
- REAL x, REAL y, REAL width, REAL height,
- GpTexture **texture);
-
-GpStatus WINGDIPAPI
-GdipCreateTexture2I(GpImage *image, GpWrapMode wrapmode, INT x,
- INT y, INT width, INT height, GpTexture **texture);
-
-GpStatus WINGDIPAPI
-GdipCreateTextureIAI(GpImage *image, GDIPCONST GpImageAttributes *imageAttributes,
- INT x, INT y, INT width, INT height,
- GpTexture **texture);
-
-
-GpStatus WINGDIPAPI
-GdipGetTextureTransform(GpTexture *brush, GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipSetTextureTransform(GpTexture *brush, GDIPCONST GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipResetTextureTransform(GpTexture* brush);
-
-GpStatus WINGDIPAPI
-GdipMultiplyTextureTransform(GpTexture* brush, GDIPCONST GpMatrix *matrix,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipTranslateTextureTransform(GpTexture* brush, REAL dx, REAL dy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipScaleTextureTransform(GpTexture* brush, REAL sx, REAL sy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipRotateTextureTransform(GpTexture* brush, REAL angle, GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipSetTextureWrapMode(GpTexture *brush, GpWrapMode wrapmode);
-
-GpStatus WINGDIPAPI
-GdipGetTextureWrapMode(GpTexture *brush, GpWrapMode *wrapmode);
-
-GpStatus WINGDIPAPI
-GdipGetTextureImage(GpTexture *brush, GpImage **image);
-
-//----------------------------------------------------------------------------
-// Solid Brush methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateSolidFill(ARGB color, GpSolidFill **brush);
-
-GpStatus WINGDIPAPI
-GdipSetSolidFillColor(GpSolidFill *brush, ARGB color);
-
-GpStatus WINGDIPAPI
-GdipGetSolidFillColor(GpSolidFill *brush, ARGB *color);
-
-//----------------------------------------------------------------------------
-// LineBrush methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateLineBrush(GDIPCONST GpPointF* point1,
- GDIPCONST GpPointF* point2,
- ARGB color1, ARGB color2,
- GpWrapMode wrapMode,
- GpLineGradient **lineGradient);
-
-GpStatus WINGDIPAPI
-GdipCreateLineBrushI(GDIPCONST GpPoint* point1,
- GDIPCONST GpPoint* point2,
- ARGB color1, ARGB color2,
- GpWrapMode wrapMode,
- GpLineGradient **lineGradient);
-
-GpStatus WINGDIPAPI
-GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect,
- ARGB color1, ARGB color2,
- LinearGradientMode mode,
- GpWrapMode wrapMode,
- GpLineGradient **lineGradient);
-
-GpStatus WINGDIPAPI
-GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect,
- ARGB color1, ARGB color2,
- LinearGradientMode mode,
- GpWrapMode wrapMode,
- GpLineGradient **lineGradient);
-
-GpStatus WINGDIPAPI
-GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect,
- ARGB color1, ARGB color2,
- REAL angle,
- BOOL isAngleScalable,
- GpWrapMode wrapMode,
- GpLineGradient **lineGradient);
-
-GpStatus WINGDIPAPI
-GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect,
- ARGB color1, ARGB color2,
- REAL angle,
- BOOL isAngleScalable,
- GpWrapMode wrapMode,
- GpLineGradient **lineGradient);
-
-GpStatus WINGDIPAPI
-GdipSetLinePoints(GpLineGradient *brush,
- GDIPCONST GpPointF* point1,
- GDIPCONST GpPointF* point2);
-
-GpStatus WINGDIPAPI
-GdipSetLinePointsI(GpLineGradient *brush,
- GDIPCONST GpPoint* point1,
- GDIPCONST GpPoint* point2);
-
-GpStatus WINGDIPAPI
-GdipGetLinePoints(GpLineGradient *brush, GpPointF* points);
-
-GpStatus WINGDIPAPI
-GdipGetLinePointsI(GpLineGradient *brush, GpPoint* points);
-
-GpStatus WINGDIPAPI
-GdipSetLineColors(GpLineGradient *brush, ARGB color1, ARGB color2);
-
-GpStatus WINGDIPAPI
-GdipGetLineColors(GpLineGradient *brush, ARGB* colors);
-
-GpStatus WINGDIPAPI
-GdipGetLineRect(GpLineGradient *brush, GpRectF *rect);
-
-GpStatus WINGDIPAPI
-GdipGetLineRectI(GpLineGradient *brush, GpRect *rect);
-
-GpStatus WINGDIPAPI
-GdipSetLineGammaCorrection(GpLineGradient *brush, BOOL useGammaCorrection);
-
-GpStatus WINGDIPAPI
-GdipGetLineGammaCorrection(GpLineGradient *brush, BOOL *useGammaCorrection);
-
-GpStatus WINGDIPAPI
-GdipGetLineBlendCount(GpLineGradient *brush, INT *count);
-
-GpStatus WINGDIPAPI
-GdipGetLineBlend(GpLineGradient *brush, REAL *blend, REAL* positions,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipSetLineBlend(GpLineGradient *brush, GDIPCONST REAL *blend,
- GDIPCONST REAL* positions, INT count);
-
-GpStatus WINGDIPAPI
-GdipGetLinePresetBlendCount(GpLineGradient *brush, INT *count);
-
-GpStatus WINGDIPAPI
-GdipGetLinePresetBlend(GpLineGradient *brush, ARGB *blend,
- REAL* positions, INT count);
-
-GpStatus WINGDIPAPI
-GdipSetLinePresetBlend(GpLineGradient *brush, GDIPCONST ARGB *blend,
- GDIPCONST REAL* positions, INT count);
-
-GpStatus WINGDIPAPI
-GdipSetLineSigmaBlend(GpLineGradient *brush, REAL focus, REAL scale);
-
-GpStatus WINGDIPAPI
-GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus, REAL scale);
-
-GpStatus WINGDIPAPI
-GdipSetLineWrapMode(GpLineGradient *brush, GpWrapMode wrapmode);
-
-GpStatus WINGDIPAPI
-GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapmode);
-
-GpStatus WINGDIPAPI
-GdipGetLineTransform(GpLineGradient *brush, GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipSetLineTransform(GpLineGradient *brush, GDIPCONST GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipResetLineTransform(GpLineGradient* brush);
-
-GpStatus WINGDIPAPI
-GdipMultiplyLineTransform(GpLineGradient* brush, GDIPCONST GpMatrix *matrix,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipTranslateLineTransform(GpLineGradient* brush, REAL dx, REAL dy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipScaleLineTransform(GpLineGradient* brush, REAL sx, REAL sy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipRotateLineTransform(GpLineGradient* brush, REAL angle, GpMatrixOrder order);
-
-//----------------------------------------------------------------------------
-// PathGradient Brush
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreatePathGradient(GDIPCONST GpPointF* points,
- INT count,
- GpWrapMode wrapMode,
- GpPathGradient **polyGradient);
-
-GpStatus WINGDIPAPI
-GdipCreatePathGradientI(GDIPCONST GpPoint* points,
- INT count,
- GpWrapMode wrapMode,
- GpPathGradient **polyGradient);
-
-GpStatus WINGDIPAPI
-GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
- GpPathGradient **polyGradient);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientCenterColor(
- GpPathGradient *brush, ARGB* colors);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientCenterColor(
- GpPathGradient *brush, ARGB colors);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientSurroundColorsWithCount(
- GpPathGradient *brush, ARGB* color, INT* count);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientSurroundColorsWithCount(
- GpPathGradient *brush,
- GDIPCONST ARGB* color, INT* count);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientPath(GpPathGradient *brush, GpPath *path);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientPath(GpPathGradient *brush, GDIPCONST GpPath *path);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientCenterPoint(
- GpPathGradient *brush, GpPointF* points);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientCenterPointI(
- GpPathGradient *brush, GpPoint* points);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientCenterPoint(
- GpPathGradient *brush, GDIPCONST GpPointF* points);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientCenterPointI(
- GpPathGradient *brush, GDIPCONST GpPoint* points);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientPointCount(GpPathGradient *brush, INT* count);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientSurroundColorCount(GpPathGradient *brush, INT* count);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientGammaCorrection(GpPathGradient *brush, BOOL useGammaCorrection);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientGammaCorrection(GpPathGradient *brush, BOOL *useGammaCorrection);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientBlendCount(GpPathGradient *brush,
- INT *count);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientBlend(GpPathGradient *brush,
- REAL *blend, REAL *positions, INT count);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientBlend(GpPathGradient *brush,
- GDIPCONST REAL *blend, GDIPCONST REAL *positions, INT count);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientPresetBlendCount(GpPathGradient *brush, INT *count);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientPresetBlend(GpPathGradient *brush, ARGB *blend,
- REAL* positions, INT count);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientPresetBlend(GpPathGradient *brush, GDIPCONST ARGB *blend,
- GDIPCONST REAL* positions, INT count);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientSigmaBlend(GpPathGradient *brush, REAL focus, REAL scale);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientLinearBlend(GpPathGradient *brush, REAL focus, REAL scale);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientWrapMode(GpPathGradient *brush,
- GpWrapMode *wrapmode);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientWrapMode(GpPathGradient *brush,
- GpWrapMode wrapmode);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientTransform(GpPathGradient *brush,
- GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientTransform(GpPathGradient *brush,
- GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipResetPathGradientTransform(GpPathGradient* brush);
-
-GpStatus WINGDIPAPI
-GdipMultiplyPathGradientTransform(GpPathGradient* brush, GDIPCONST GpMatrix *matrix,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipTranslatePathGradientTransform(GpPathGradient* brush, REAL dx, REAL dy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipScalePathGradientTransform(GpPathGradient* brush, REAL sx, REAL sy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipRotatePathGradientTransform(GpPathGradient* brush, REAL angle,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipGetPathGradientFocusScales(GpPathGradient *brush, REAL* xScale, REAL* yScale);
-
-GpStatus WINGDIPAPI
-GdipSetPathGradientFocusScales(GpPathGradient *brush, REAL xScale, REAL yScale);
-
-//----------------------------------------------------------------------------
-// Pen methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreatePen1(ARGB color, REAL width, GpUnit unit, GpPen **pen);
-
-GpStatus WINGDIPAPI
-GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit,
- GpPen **pen);
-
-GpStatus WINGDIPAPI
-GdipClonePen(GpPen *pen, GpPen **clonepen);
-
-GpStatus WINGDIPAPI
-GdipDeletePen(GpPen *pen);
-
-GpStatus WINGDIPAPI
-GdipSetPenWidth(GpPen *pen, REAL width);
-
-GpStatus WINGDIPAPI
-GdipGetPenWidth(GpPen *pen, REAL *width);
-
-GpStatus WINGDIPAPI
-GdipSetPenUnit(GpPen *pen, GpUnit unit);
-
-GpStatus WINGDIPAPI
-GdipGetPenUnit(GpPen *pen, GpUnit *unit);
-
-#ifdef DCR_USE_NEW_197819
-GpStatus WINGDIPAPI
-GdipSetPenLineCap197819(GpPen *pen, GpLineCap startCap, GpLineCap endCap,
- GpDashCap dashCap);
-#else
-GpStatus WINGDIPAPI
-GdipSetPenLineCap(GpPen *pen, GpLineCap startCap, GpLineCap endCap,
- GpLineCap dashCap);
-#endif // DCR_USE_NEW_197819
-
-
-GpStatus WINGDIPAPI
-GdipSetPenStartCap(GpPen *pen, GpLineCap startCap);
-
-GpStatus WINGDIPAPI
-GdipSetPenEndCap(GpPen *pen, GpLineCap endCap);
-
-#ifdef DCR_USE_NEW_197819
-GpStatus WINGDIPAPI
-GdipSetPenDashCap197819(GpPen *pen, GpDashCap dashCap);
-#else
-GpStatus WINGDIPAPI
-GdipSetPenDashCap(GpPen *pen, GpLineCap dashCap);
-#endif // DCR_USE_NEW_197819
-
-GpStatus WINGDIPAPI
-GdipGetPenStartCap(GpPen *pen, GpLineCap *startCap);
-
-GpStatus WINGDIPAPI
-GdipGetPenEndCap(GpPen *pen, GpLineCap *endCap);
-
-#ifdef DCR_USE_NEW_197819
-GpStatus WINGDIPAPI
-GdipGetPenDashCap197819(GpPen *pen, GpDashCap *dashCap);
-#else
-GpStatus WINGDIPAPI
-GdipGetPenDashCap(GpPen *pen, GpLineCap *dashCap);
-#endif // DCR_USE_NEW_197819
-
-GpStatus WINGDIPAPI
-GdipSetPenLineJoin(GpPen *pen, GpLineJoin lineJoin);
-
-GpStatus WINGDIPAPI
-GdipGetPenLineJoin(GpPen *pen, GpLineJoin *lineJoin);
-
-GpStatus WINGDIPAPI
-GdipSetPenCustomStartCap(GpPen *pen, GpCustomLineCap* customCap);
-
-GpStatus WINGDIPAPI
-GdipGetPenCustomStartCap(GpPen *pen, GpCustomLineCap** customCap);
-
-GpStatus WINGDIPAPI
-GdipSetPenCustomEndCap(GpPen *pen, GpCustomLineCap* customCap);
-
-GpStatus WINGDIPAPI
-GdipGetPenCustomEndCap(GpPen *pen, GpCustomLineCap** customCap);
-
-GpStatus WINGDIPAPI
-GdipSetPenMiterLimit(GpPen *pen, REAL miterLimit);
-
-GpStatus WINGDIPAPI
-GdipGetPenMiterLimit(GpPen *pen, REAL *miterLimit);
-
-GpStatus WINGDIPAPI
-GdipSetPenMode(GpPen *pen, GpPenAlignment penMode);
-
-GpStatus WINGDIPAPI
-GdipGetPenMode(GpPen *pen, GpPenAlignment *penMode);
-
-GpStatus WINGDIPAPI
-GdipSetPenTransform(GpPen *pen, GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipGetPenTransform(GpPen *pen, GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipResetPenTransform(GpPen *pen);
-
-GpStatus WINGDIPAPI
-GdipMultiplyPenTransform(GpPen *pen, GDIPCONST GpMatrix *matrix,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipTranslatePenTransform(GpPen *pen, REAL dx, REAL dy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipScalePenTransform(GpPen *pen, REAL sx, REAL sy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipRotatePenTransform(GpPen *pen, REAL angle, GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipSetPenColor(GpPen *pen, ARGB argb);
-
-GpStatus WINGDIPAPI
-GdipGetPenColor(GpPen *pen, ARGB *argb);
-
-GpStatus WINGDIPAPI
-GdipSetPenBrushFill(GpPen *pen, GpBrush *brush);
-
-GpStatus WINGDIPAPI
-GdipGetPenBrushFill(GpPen *pen, GpBrush **brush);
-
-GpStatus WINGDIPAPI
-GdipGetPenFillType(GpPen *pen, GpPenType* type);
-
-GpStatus WINGDIPAPI
-GdipGetPenDashStyle(GpPen *pen, GpDashStyle *dashstyle);
-
-GpStatus WINGDIPAPI
-GdipSetPenDashStyle(GpPen *pen, GpDashStyle dashstyle);
-
-GpStatus WINGDIPAPI
-GdipGetPenDashOffset(GpPen *pen, REAL *offset);
-
-GpStatus WINGDIPAPI
-GdipSetPenDashOffset(GpPen *pen, REAL offset);
-
-GpStatus WINGDIPAPI
-GdipGetPenDashCount(GpPen *pen, INT *count);
-
-GpStatus WINGDIPAPI
-GdipSetPenDashArray(GpPen *pen, GDIPCONST REAL *dash, INT count);
-
-GpStatus WINGDIPAPI
-GdipGetPenDashArray(GpPen *pen, REAL *dash, INT count);
-
-GpStatus WINGDIPAPI
-GdipGetPenCompoundCount(GpPen *pen, INT *count);
-
-GpStatus WINGDIPAPI
-GdipSetPenCompoundArray(GpPen *pen, GDIPCONST REAL *dash, INT count);
-
-GpStatus WINGDIPAPI
-GdipGetPenCompoundArray(GpPen *pen, REAL *dash, INT count);
-
-//----------------------------------------------------------------------------
-// CustomLineCap methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath,
- GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap);
-
-GpStatus WINGDIPAPI
-GdipDeleteCustomLineCap(GpCustomLineCap* customCap);
-
-GpStatus WINGDIPAPI
-GdipCloneCustomLineCap(GpCustomLineCap* customCap,
- GpCustomLineCap** clonedCap);
-
-GpStatus WINGDIPAPI
-GdipGetCustomLineCapType(GpCustomLineCap* customCap,
- CustomLineCapType* capType);
-
-GpStatus WINGDIPAPI
-GdipSetCustomLineCapStrokeCaps(GpCustomLineCap* customCap,
- GpLineCap startCap, GpLineCap endCap);
-
-GpStatus WINGDIPAPI
-GdipGetCustomLineCapStrokeCaps(GpCustomLineCap* customCap,
- GpLineCap* startCap, GpLineCap* endCap);
-
-GpStatus WINGDIPAPI
-GdipSetCustomLineCapStrokeJoin(GpCustomLineCap* customCap, GpLineJoin lineJoin);
-
-GpStatus WINGDIPAPI
-GdipGetCustomLineCapStrokeJoin(GpCustomLineCap* customCap, GpLineJoin* lineJoin);
-
-GpStatus WINGDIPAPI
-GdipSetCustomLineCapBaseCap(GpCustomLineCap* customCap, GpLineCap baseCap);
-
-GpStatus WINGDIPAPI
-GdipGetCustomLineCapBaseCap(GpCustomLineCap* customCap, GpLineCap* baseCap);
-
-GpStatus WINGDIPAPI
-GdipSetCustomLineCapBaseInset(GpCustomLineCap* customCap, REAL inset);
-
-GpStatus WINGDIPAPI
-GdipGetCustomLineCapBaseInset(GpCustomLineCap* customCap, REAL* inset);
-
-GpStatus WINGDIPAPI
-GdipSetCustomLineCapWidthScale(GpCustomLineCap* customCap, REAL widthScale);
-
-GpStatus WINGDIPAPI
-GdipGetCustomLineCapWidthScale(GpCustomLineCap* customCap, REAL* widthScale);
-
-//----------------------------------------------------------------------------
-// AdjustableArrowCap methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL isFilled,
- GpAdjustableArrowCap **cap);
-
-GpStatus WINGDIPAPI
-GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL height);
-
-GpStatus WINGDIPAPI
-GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL* height);
-
-GpStatus WINGDIPAPI
-GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL width);
-
-GpStatus WINGDIPAPI
-GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL* width);
-
-GpStatus WINGDIPAPI
-GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL middleInset);
-
-GpStatus WINGDIPAPI
-GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL* middleInset);
-
-GpStatus WINGDIPAPI
-GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL fillState);
-
-GpStatus WINGDIPAPI
-GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL* fillState);
-
-//----------------------------------------------------------------------------
-// Image methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipLoadImageFromStream(IStream* stream, GpImage **image);
-
-GpStatus WINGDIPAPI
-GdipLoadImageFromFile(GDIPCONST WCHAR* filename, GpImage **image);
-
-GpStatus WINGDIPAPI
-GdipLoadImageFromStreamICM(IStream* stream, GpImage **image);
-
-GpStatus WINGDIPAPI
-GdipLoadImageFromFileICM(GDIPCONST WCHAR* filename, GpImage **image);
-
-GpStatus WINGDIPAPI
-GdipCloneImage(GpImage *image, GpImage **cloneImage);
-
-GpStatus WINGDIPAPI
-GdipDisposeImage(GpImage *image);
-
-GpStatus WINGDIPAPI
-GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR* filename,
- GDIPCONST CLSID* clsidEncoder, GDIPCONST EncoderParameters* encoderParams);
-
-GpStatus WINGDIPAPI
-GdipSaveImageToStream(GpImage *image, IStream* stream,
- GDIPCONST CLSID* clsidEncoder, GDIPCONST EncoderParameters* encoderParams);
-
-GpStatus WINGDIPAPI
-GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters* encoderParams);
-
-GpStatus WINGDIPAPI
-GdipSaveAddImage(GpImage *image, GpImage* newImage,
- GDIPCONST EncoderParameters* encoderParams);
-
-GpStatus WINGDIPAPI
-GdipGetImageGraphicsContext(GpImage *image, GpGraphics **graphics);
-
-GpStatus WINGDIPAPI
-GdipGetImageBounds(GpImage *image, GpRectF *srcRect, GpUnit *srcUnit);
-
-GpStatus WINGDIPAPI
-GdipGetImageDimension(GpImage *image, REAL *width, REAL *height);
-
-GpStatus WINGDIPAPI
-GdipGetImageType(GpImage *image, ImageType *type);
-
-GpStatus WINGDIPAPI
-GdipGetImageWidth(GpImage *image, UINT *width);
-
-GpStatus WINGDIPAPI
-GdipGetImageHeight(GpImage *image, UINT *height);
-
-GpStatus WINGDIPAPI
-GdipGetImageHorizontalResolution(GpImage *image, REAL *resolution);
-
-GpStatus WINGDIPAPI
-GdipGetImageVerticalResolution(GpImage *image, REAL *resolution);
-
-GpStatus WINGDIPAPI
-GdipGetImageFlags(GpImage *image, UINT *flags);
-
-GpStatus WINGDIPAPI
-GdipGetImageRawFormat(GpImage *image, GUID *format);
-
-GpStatus WINGDIPAPI
-GdipGetImagePixelFormat(GpImage *image, PixelFormat *format);
-
-GpStatus WINGDIPAPI
-GdipGetImageThumbnail(GpImage *image, UINT thumbWidth, UINT thumbHeight,
- GpImage **thumbImage,
- GetThumbnailImageAbort callback, VOID * callbackData);
-
-GpStatus WINGDIPAPI
-GdipGetEncoderParameterListSize(GpImage *image, GDIPCONST CLSID* clsidEncoder,
- UINT* size);
-
-GpStatus WINGDIPAPI
-GdipGetEncoderParameterList(GpImage *image, GDIPCONST CLSID* clsidEncoder,
- UINT size, EncoderParameters* buffer);
-
-GpStatus WINGDIPAPI
-GdipImageGetFrameDimensionsCount(GpImage* image, UINT* count);
-
-GpStatus WINGDIPAPI
-GdipImageGetFrameDimensionsList(GpImage* image, GUID* dimensionIDs, UINT count);
-
-GpStatus WINGDIPAPI
-GdipImageGetFrameCount(GpImage *image, GDIPCONST GUID* dimensionID, UINT* count);
-
-GpStatus WINGDIPAPI
-GdipImageSelectActiveFrame(GpImage *image, GDIPCONST GUID* dimensionID,
- UINT frameIndex);
-
-GpStatus WINGDIPAPI
-GdipImageRotateFlip(GpImage *image, RotateFlipType rfType);
-
-GpStatus WINGDIPAPI
-GdipGetImagePalette(GpImage *image, ColorPalette *palette, INT size);
-
-GpStatus WINGDIPAPI
-GdipSetImagePalette(GpImage *image, GDIPCONST ColorPalette *palette);
-
-GpStatus WINGDIPAPI
-GdipGetImagePaletteSize(GpImage *image, INT *size);
-
-GpStatus WINGDIPAPI
-GdipGetPropertyCount(GpImage *image, UINT* numOfProperty);
-
-GpStatus WINGDIPAPI
-GdipGetPropertyIdList(GpImage *image, UINT numOfProperty, PROPID* list);
-
-GpStatus WINGDIPAPI
-GdipGetPropertyItemSize(GpImage *image, PROPID propId, UINT* size);
-
-GpStatus WINGDIPAPI
-GdipGetPropertyItem(GpImage *image, PROPID propId,UINT propSize,
- PropertyItem* buffer);
-
-GpStatus WINGDIPAPI
-GdipGetPropertySize(GpImage *image, UINT* totalBufferSize, UINT* numProperties);
-
-GpStatus WINGDIPAPI
-GdipGetAllPropertyItems(GpImage *image, UINT totalBufferSize,
- UINT numProperties, PropertyItem* allItems);
-
-GpStatus WINGDIPAPI
-GdipRemovePropertyItem(GpImage *image, PROPID propId);
-
-GpStatus WINGDIPAPI
-GdipSetPropertyItem(GpImage *image, GDIPCONST PropertyItem* item);
-
-GpStatus WINGDIPAPI
-GdipImageForceValidation(GpImage *image);
-
-GpStatus WINGDIPAPI
-GdipGetImageLayout(GpImage *image, ImageLayout* layout);
-
-GpStatus WINGDIPAPI
-GdipSetImageLayout(GpImage *image, GDIPCONST ImageLayout layout);
-
-//----------------------------------------------------------------------------
-// Bitmap methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromStream(IStream* stream, GpBitmap **bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromFile(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromStreamICM(IStream* stream, GpBitmap **bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromFileICM(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromScan0(INT width,
- INT height,
- INT stride,
- PixelFormat format,
- BYTE* scan0,
- GpBitmap** bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromGraphics(INT width,
- INT height,
- GpGraphics* target,
- GpBitmap** bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromDirectDrawSurface(IDirectDrawSurface7* surface,
- GpBitmap** bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromGdiDib(GDIPCONST BITMAPINFO* gdiBitmapInfo,
- VOID* gdiBitmapData,
- GpBitmap** bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromHBITMAP(HBITMAP hbm,
- HPALETTE hpal,
- GpBitmap** bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
- HBITMAP* hbmReturn,
- ARGB background);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromHICON(HICON hicon,
- GpBitmap** bitmap);
-
-GpStatus WINGDIPAPI
-GdipCreateHICONFromBitmap(GpBitmap* bitmap,
- HICON* hbmReturn);
-
-GpStatus WINGDIPAPI
-GdipCreateBitmapFromResource(HINSTANCE hInstance,
- GDIPCONST WCHAR* lpBitmapName,
- GpBitmap** bitmap);
-
-GpStatus WINGDIPAPI
-GdipCloneBitmapArea(REAL x, REAL y, REAL width, REAL height,
- PixelFormat format,
- GpBitmap *srcBitmap,
- GpBitmap **dstBitmap);
-
-GpStatus WINGDIPAPI
-GdipCloneBitmapAreaI(INT x,
- INT y,
- INT width,
- INT height,
- PixelFormat format,
- GpBitmap *srcBitmap,
- GpBitmap **dstBitmap);
-
-GpStatus WINGDIPAPI
-GdipBitmapLockBits(GpBitmap* bitmap,
- GDIPCONST GpRect* rect,
- UINT flags,
- PixelFormat format,
- BitmapData* lockedBitmapData);
-
-GpStatus WINGDIPAPI
-GdipBitmapUnlockBits(GpBitmap* bitmap,
- BitmapData* lockedBitmapData);
-
-GpStatus WINGDIPAPI
-GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, ARGB *color);
-
-GpStatus WINGDIPAPI
-GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, ARGB color);
-
-GpStatus WINGDIPAPI
-GdipBitmapSetResolution(GpBitmap* bitmap, REAL xdpi, REAL ydpi);
-
-//----------------------------------------------------------------------------
-// ImageAttributes methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateImageAttributes(GpImageAttributes **imageattr);
-
-GpStatus WINGDIPAPI
-GdipCloneImageAttributes(GDIPCONST GpImageAttributes *imageattr,
- GpImageAttributes **cloneImageattr);
-
-GpStatus WINGDIPAPI
-GdipDisposeImageAttributes(GpImageAttributes *imageattr);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesToIdentity(GpImageAttributes *imageattr,
- ColorAdjustType type);
-GpStatus WINGDIPAPI
-GdipResetImageAttributes(GpImageAttributes *imageattr,
- ColorAdjustType type);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesColorMatrix(GpImageAttributes *imageattr,
- ColorAdjustType type,
- BOOL enableFlag,
- GDIPCONST ColorMatrix* colorMatrix,
- GDIPCONST ColorMatrix* grayMatrix,
- ColorMatrixFlags flags);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesThreshold(GpImageAttributes *imageattr,
- ColorAdjustType type,
- BOOL enableFlag,
- REAL threshold);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesGamma(GpImageAttributes *imageattr,
- ColorAdjustType type,
- BOOL enableFlag,
- REAL gamma);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesNoOp(GpImageAttributes *imageattr,
- ColorAdjustType type,
- BOOL enableFlag);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesColorKeys(GpImageAttributes *imageattr,
- ColorAdjustType type,
- BOOL enableFlag,
- ARGB colorLow,
- ARGB colorHigh);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesOutputChannel(GpImageAttributes *imageattr,
- ColorAdjustType type,
- BOOL enableFlag,
- ColorChannelFlags channelFlags);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesOutputChannelColorProfile(GpImageAttributes *imageattr,
- ColorAdjustType type,
- BOOL enableFlag,
- GDIPCONST WCHAR *colorProfileFilename);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesRemapTable(GpImageAttributes *imageattr,
- ColorAdjustType type,
- BOOL enableFlag,
- UINT mapSize,
- GDIPCONST ColorMap *map);
-GpStatus WINGDIPAPI
-GdipSetImageAttributesWrapMode(
- GpImageAttributes *imageAttr,
- WrapMode wrap,
- ARGB argb,
- BOOL clamp
-);
-
-GpStatus WINGDIPAPI
-GdipSetImageAttributesICMMode(
- GpImageAttributes *imageAttr,
- BOOL on
-);
-
-GpStatus WINGDIPAPI
-GdipGetImageAttributesAdjustedPalette(
- GpImageAttributes *imageAttr,
- ColorPalette * colorPalette,
- ColorAdjustType colorAdjustType
-);
-
-//----------------------------------------------------------------------------
-// Graphics methods
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipFlush(GpGraphics *graphics, GpFlushIntention intention);
-
-GpStatus WINGDIPAPI
-GdipCreateFromHDC(HDC hdc, GpGraphics **graphics);
-
-GpStatus WINGDIPAPI
-GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **graphics);
-
-GpStatus WINGDIPAPI
-GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics);
-
-GpStatus WINGDIPAPI
-GdipCreateFromHWNDICM(HWND hwnd, GpGraphics **graphics);
-
-GpStatus WINGDIPAPI
-GdipDeleteGraphics(GpGraphics *graphics);
-
-GpStatus WINGDIPAPI
-GdipGetDC(GpGraphics* graphics, HDC * hdc);
-
-GpStatus WINGDIPAPI
-GdipReleaseDC(GpGraphics* graphics, HDC hdc);
-
-GpStatus WINGDIPAPI
-GdipSetCompositingMode(GpGraphics *graphics, CompositingMode compositingMode);
-
-GpStatus WINGDIPAPI
-GdipGetCompositingMode(GpGraphics *graphics, CompositingMode *compositingMode);
-
-GpStatus WINGDIPAPI
-GdipSetRenderingOrigin(GpGraphics *graphics, INT x, INT y);
-
-GpStatus WINGDIPAPI
-GdipGetRenderingOrigin(GpGraphics *graphics, INT *x, INT *y);
-
-GpStatus WINGDIPAPI
-GdipSetCompositingQuality(GpGraphics *graphics, CompositingQuality compositingQuality);
-
-GpStatus WINGDIPAPI
-GdipGetCompositingQuality(GpGraphics *graphics, CompositingQuality *compositingQuality);
-
-GpStatus WINGDIPAPI
-GdipSetSmoothingMode(GpGraphics *graphics, SmoothingMode smoothingMode);
-
-GpStatus WINGDIPAPI
-GdipGetSmoothingMode(GpGraphics *graphics, SmoothingMode *smoothingMode);
-
-GpStatus WINGDIPAPI
-GdipSetPixelOffsetMode(GpGraphics* graphics, PixelOffsetMode pixelOffsetMode);
-
-GpStatus WINGDIPAPI
-GdipGetPixelOffsetMode(GpGraphics *graphics, PixelOffsetMode *pixelOffsetMode);
-
-GpStatus WINGDIPAPI
-GdipSetTextRenderingHint(GpGraphics *graphics, TextRenderingHint mode);
-
-GpStatus WINGDIPAPI
-GdipGetTextRenderingHint(GpGraphics *graphics, TextRenderingHint *mode);
-
-#ifdef DCR_USE_NEW_188922
-GpStatus WINGDIPAPI
-GdipSetTextContrast(GpGraphics *graphics, UINT contrast);
-
-GpStatus WINGDIPAPI
-GdipGetTextContrast(GpGraphics *graphics, UINT * contrast);
-#else
-GpStatus WINGDIPAPI
-GdipSetTextGammaValue(GpGraphics *graphics, UINT gammaValue);
-
-GpStatus WINGDIPAPI
-GdipGetTextGammaValue(GpGraphics *graphics, UINT * gammaValue);
-#endif // DCR_USE_NEW_188922
-
-
-GpStatus WINGDIPAPI
-GdipSetInterpolationMode(GpGraphics *graphics, InterpolationMode interpolationMode);
-
-GpStatus WINGDIPAPI
-GdipGetInterpolationMode(GpGraphics *graphics, InterpolationMode *interpolationMode);
-
-GpStatus WINGDIPAPI
-GdipSetWorldTransform(GpGraphics *graphics, GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipResetWorldTransform(GpGraphics *graphics);
-
-GpStatus WINGDIPAPI
-GdipMultiplyWorldTransform(GpGraphics *graphics, GDIPCONST GpMatrix *matrix,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipTranslateWorldTransform(GpGraphics *graphics, REAL dx, REAL dy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipScaleWorldTransform(GpGraphics *graphics, REAL sx, REAL sy,
- GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipRotateWorldTransform(GpGraphics *graphics, REAL angle, GpMatrixOrder order);
-
-GpStatus WINGDIPAPI
-GdipGetWorldTransform(GpGraphics *graphics, GpMatrix *matrix);
-
-GpStatus WINGDIPAPI
-GdipResetPageTransform(GpGraphics *graphics);
-
-GpStatus WINGDIPAPI
-GdipGetPageUnit(GpGraphics *graphics, GpUnit *unit);
-
-GpStatus WINGDIPAPI
-GdipGetPageScale(GpGraphics *graphics, REAL *scale);
-
-GpStatus WINGDIPAPI
-GdipSetPageUnit(GpGraphics *graphics, GpUnit unit);
-
-GpStatus WINGDIPAPI
-GdipSetPageScale(GpGraphics *graphics, REAL scale);
-
-GpStatus WINGDIPAPI
-GdipGetDpiX(GpGraphics *graphics, REAL* dpi);
-
-GpStatus WINGDIPAPI
-GdipGetDpiY(GpGraphics *graphics, REAL* dpi);
-
-GpStatus WINGDIPAPI
-GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace destSpace,
- GpCoordinateSpace srcSpace, GpPointF *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipTransformPointsI(GpGraphics *graphics, GpCoordinateSpace destSpace,
- GpCoordinateSpace srcSpace, GpPoint *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipGetNearestColor(GpGraphics *graphics, ARGB* argb);
-
-// Create the Win9x Halftone Palette (even on NT) with correct Desktop colors
-HPALETTE WINGDIPAPI
-GdipCreateHalftonePalette();
-
-GpStatus WINGDIPAPI
-GdipDrawLine(GpGraphics *graphics, GpPen *pen, REAL x1, REAL y1,
- REAL x2, REAL y2);
-
-GpStatus WINGDIPAPI
-GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1,
- INT x2, INT y2);
-
-GpStatus WINGDIPAPI
-GdipDrawLines(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawLinesI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x, REAL y,
- REAL width, REAL height, REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
- INT width, INT height, REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipDrawBezier(GpGraphics *graphics, GpPen *pen, REAL x1, REAL y1,
- REAL x2, REAL y2, REAL x3, REAL y3, REAL x4, REAL y4);
-
-GpStatus WINGDIPAPI
-GdipDrawBezierI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1,
- INT x2, INT y2, INT x3, INT y3, INT x4, INT y4);
-
-GpStatus WINGDIPAPI
-GdipDrawBeziers(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawBeziersI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawRectangle(GpGraphics *graphics, GpPen *pen, REAL x, REAL y,
- REAL width, REAL height);
-
-GpStatus WINGDIPAPI
-GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
- INT width, INT height);
-
-GpStatus WINGDIPAPI
-GdipDrawRectangles(GpGraphics *graphics, GpPen *pen, GDIPCONST GpRectF *rects,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawRectanglesI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpRect *rects,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x, REAL y,
- REAL width, REAL height);
-
-GpStatus WINGDIPAPI
-GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
- INT width, INT height);
-
-GpStatus WINGDIPAPI
-GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x, REAL y,
- REAL width, REAL height, REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipDrawPieI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
- INT width, INT height, REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipDrawPolygon(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawPolygonI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path);
-
-GpStatus WINGDIPAPI
-GdipDrawCurve(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawCurveI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
- INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawCurve2(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
- INT count, REAL tension);
-
-GpStatus WINGDIPAPI
-GdipDrawCurve2I(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
- INT count, REAL tension);
-
-GpStatus WINGDIPAPI
-GdipDrawCurve3(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
- INT count, INT offset, INT numberOfSegments, REAL tension);
-
-GpStatus WINGDIPAPI
-GdipDrawCurve3I(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
- INT count, INT offset, INT numberOfSegments, REAL tension);
-
-GpStatus WINGDIPAPI
-GdipDrawClosedCurve(GpGraphics *graphics, GpPen *pen,
- GDIPCONST GpPointF *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawClosedCurveI(GpGraphics *graphics, GpPen *pen,
- GDIPCONST GpPoint *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawClosedCurve2(GpGraphics *graphics, GpPen *pen,
- GDIPCONST GpPointF *points, INT count, REAL tension);
-
-GpStatus WINGDIPAPI
-GdipDrawClosedCurve2I(GpGraphics *graphics, GpPen *pen,
- GDIPCONST GpPoint *points, INT count, REAL tension);
-
-GpStatus WINGDIPAPI
-GdipGraphicsClear(GpGraphics *graphics, ARGB color);
-
-GpStatus WINGDIPAPI
-GdipFillRectangle(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y,
- REAL width, REAL height);
-
-GpStatus WINGDIPAPI
-GdipFillRectangleI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
- INT width, INT height);
-
-GpStatus WINGDIPAPI
-GdipFillRectangles(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpRectF *rects, INT count);
-
-GpStatus WINGDIPAPI
-GdipFillRectanglesI(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpRect *rects, INT count);
-
-GpStatus WINGDIPAPI
-GdipFillPolygon(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpPointF *points, INT count, GpFillMode fillMode);
-
-GpStatus WINGDIPAPI
-GdipFillPolygonI(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpPoint *points, INT count, GpFillMode fillMode);
-
-GpStatus WINGDIPAPI
-GdipFillPolygon2(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpPointF *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipFillPolygon2I(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpPoint *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipFillEllipse(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y,
- REAL width, REAL height);
-
-GpStatus WINGDIPAPI
-GdipFillEllipseI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
- INT width, INT height);
-
-GpStatus WINGDIPAPI
-GdipFillPie(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y,
- REAL width, REAL height, REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipFillPieI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
- INT width, INT height, REAL startAngle, REAL sweepAngle);
-
-GpStatus WINGDIPAPI
-GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *path);
-
-GpStatus WINGDIPAPI
-GdipFillClosedCurve(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpPointF *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipFillClosedCurveI(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpPoint *points, INT count);
-
-GpStatus WINGDIPAPI
-GdipFillClosedCurve2(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpPointF *points, INT count,
- REAL tension, GpFillMode fillMode);
-
-GpStatus WINGDIPAPI
-GdipFillClosedCurve2I(GpGraphics *graphics, GpBrush *brush,
- GDIPCONST GpPoint *points, INT count,
- REAL tension, GpFillMode fillMode);
-
-GpStatus WINGDIPAPI
-GdipFillRegion(GpGraphics *graphics, GpBrush *brush,
- GpRegion *region);
-
-GpStatus WINGDIPAPI
-GdipDrawImage(GpGraphics *graphics, GpImage *image, REAL x, REAL y);
-
-GpStatus WINGDIPAPI
-GdipDrawImageI(GpGraphics *graphics, GpImage *image, INT x, INT y);
-
-GpStatus WINGDIPAPI
-GdipDrawImageRect(GpGraphics *graphics, GpImage *image, REAL x, REAL y,
- REAL width, REAL height);
-
-GpStatus WINGDIPAPI
-GdipDrawImageRectI(GpGraphics *graphics, GpImage *image, INT x, INT y,
- INT width, INT height);
-
-GpStatus WINGDIPAPI
-GdipDrawImagePoints(GpGraphics *graphics, GpImage *image,
- GDIPCONST GpPointF *dstpoints, INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawImagePointsI(GpGraphics *graphics, GpImage *image,
- GDIPCONST GpPoint *dstpoints, INT count);
-
-GpStatus WINGDIPAPI
-GdipDrawImagePointRect(GpGraphics *graphics, GpImage *image, REAL x,
- REAL y, REAL srcx, REAL srcy, REAL srcwidth,
- REAL srcheight, GpUnit srcUnit);
-
-GpStatus WINGDIPAPI
-GdipDrawImagePointRectI(GpGraphics *graphics, GpImage *image, INT x,
- INT y, INT srcx, INT srcy, INT srcwidth,
- INT srcheight, GpUnit srcUnit);
-
-GpStatus WINGDIPAPI
-GdipDrawImageRectRect(GpGraphics *graphics, GpImage *image, REAL dstx,
- REAL dsty, REAL dstwidth, REAL dstheight,
- REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight,
- GpUnit srcUnit,
- GDIPCONST GpImageAttributes* imageAttributes,
- DrawImageAbort callback, VOID * callbackData);
-
-GpStatus WINGDIPAPI
-GdipDrawImageRectRectI(GpGraphics *graphics, GpImage *image, INT dstx,
- INT dsty, INT dstwidth, INT dstheight,
- INT srcx, INT srcy, INT srcwidth, INT srcheight,
- GpUnit srcUnit,
- GDIPCONST GpImageAttributes* imageAttributes,
- DrawImageAbort callback, VOID * callbackData);
-
-GpStatus WINGDIPAPI
-GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image,
- GDIPCONST GpPointF *points, INT count, REAL srcx,
- REAL srcy, REAL srcwidth, REAL srcheight,
- GpUnit srcUnit,
- GDIPCONST GpImageAttributes* imageAttributes,
- DrawImageAbort callback, VOID * callbackData);
-
-GpStatus WINGDIPAPI
-GdipDrawImagePointsRectI(GpGraphics *graphics, GpImage *image,
- GDIPCONST GpPoint *points, INT count, INT srcx,
- INT srcy, INT srcwidth, INT srcheight,
- GpUnit srcUnit,
- GDIPCONST GpImageAttributes* imageAttributes,
- DrawImageAbort callback, VOID * callbackData);
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileDestPoint(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST PointF & destPoint,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileDestPointI(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST Point & destPoint,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileDestRect(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST RectF & destRect,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileDestRectI(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST Rect & destRect,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileDestPoints(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST PointF * destPoints,
- INT count,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileDestPointsI(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST Point * destPoints,
- INT count,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileSrcRectDestPoint(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST PointF & destPoint,
- GDIPCONST RectF & srcRect,
- Unit srcUnit,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileSrcRectDestPointI(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST Point & destPoint,
- GDIPCONST Rect & srcRect,
- Unit srcUnit,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileSrcRectDestRect(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST RectF & destRect,
- GDIPCONST RectF & srcRect,
- Unit srcUnit,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileSrcRectDestRectI(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST Rect & destRect,
- GDIPCONST Rect & srcRect,
- Unit srcUnit,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileSrcRectDestPoints(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST PointF * destPoints,
- INT count,
- GDIPCONST RectF & srcRect,
- Unit srcUnit,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipEnumerateMetafileSrcRectDestPointsI(
- GpGraphics * graphics,
- GDIPCONST GpMetafile * metafile,
- GDIPCONST Point * destPoints,
- INT count,
- GDIPCONST Rect & srcRect,
- Unit srcUnit,
- EnumerateMetafileProc callback,
- VOID * callbackData,
- GDIPCONST GpImageAttributes * imageAttributes
- );
-
-GpStatus WINGDIPAPI
-GdipPlayMetafileRecord(
- GDIPCONST GpMetafile * metafile,
- EmfPlusRecordType recordType,
- UINT flags,
- UINT dataSize,
- GDIPCONST BYTE * data
- );
-
-GpStatus WINGDIPAPI
-GdipSetClipGraphics(GpGraphics *graphics, GpGraphics *srcgraphics,
- CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipSetClipRect(GpGraphics *graphics, REAL x, REAL y,
- REAL width, REAL height, CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipSetClipRectI(GpGraphics *graphics, INT x, INT y,
- INT width, INT height, CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipSetClipPath(GpGraphics *graphics, GpPath *path, CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipSetClipRegion(GpGraphics *graphics, GpRegion *region,
- CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipSetClipHrgn(GpGraphics *graphics, HRGN hRgn, CombineMode combineMode);
-
-GpStatus WINGDIPAPI
-GdipResetClip(GpGraphics *graphics);
-
-GpStatus WINGDIPAPI
-GdipTranslateClip(GpGraphics *graphics, REAL dx, REAL dy);
-
-GpStatus WINGDIPAPI
-GdipTranslateClipI(GpGraphics *graphics, INT dx, INT dy);
-
-GpStatus WINGDIPAPI
-GdipGetClip(GpGraphics *graphics, GpRegion *region);
-
-GpStatus WINGDIPAPI
-GdipGetClipBounds(GpGraphics *graphics, GpRectF *rect);
-
-GpStatus WINGDIPAPI
-GdipGetClipBoundsI(GpGraphics *graphics, GpRect *rect);
-
-GpStatus WINGDIPAPI
-GdipIsClipEmpty(GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipGetVisibleClipBounds(GpGraphics *graphics, GpRectF *rect);
-
-GpStatus WINGDIPAPI
-GdipGetVisibleClipBoundsI(GpGraphics *graphics, GpRect *rect);
-
-GpStatus WINGDIPAPI
-GdipIsVisibleClipEmpty(GpGraphics *graphics, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsVisiblePoint(GpGraphics *graphics, REAL x, REAL y,
- BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsVisiblePointI(GpGraphics *graphics, INT x, INT y,
- BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsVisibleRect(GpGraphics *graphics, REAL x, REAL y,
- REAL width, REAL height, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipIsVisibleRectI(GpGraphics *graphics, INT x, INT y,
- INT width, INT height, BOOL *result);
-
-GpStatus WINGDIPAPI
-GdipSaveGraphics(GpGraphics *graphics, GraphicsState *state);
-
-GpStatus WINGDIPAPI
-GdipRestoreGraphics(GpGraphics *graphics, GraphicsState state);
-
-GpStatus WINGDIPAPI
-GdipBeginContainer(GpGraphics *graphics, GDIPCONST GpRectF* dstrect,
- GDIPCONST GpRectF *srcrect, GpUnit unit, GraphicsContainer *state);
-
-GpStatus WINGDIPAPI
-GdipBeginContainerI(GpGraphics *graphics, GDIPCONST GpRect* dstrect,
- GDIPCONST GpRect *srcrect, GpUnit unit, GraphicsContainer *state);
-
-GpStatus WINGDIPAPI
-GdipBeginContainer2(GpGraphics *graphics, GraphicsContainer* state);
-
-GpStatus WINGDIPAPI
-GdipEndContainer(GpGraphics *graphics, GraphicsContainer state);
-
-GpStatus
-GdipGetMetafileHeaderFromWmf(
- HMETAFILE hWmf,
- GDIPCONST APMFileHeader * apmFileHeader,
- MetafileHeader * header
- );
-
-GpStatus
-WINGDIPAPI
-GdipGetMetafileHeaderFromEmf(
- HENHMETAFILE hEmf,
- MetafileHeader * header
- );
-
-GpStatus
-WINGDIPAPI
-GdipGetMetafileHeaderFromFile(
- GDIPCONST WCHAR* filename,
- MetafileHeader * header
- );
-
-GpStatus
-WINGDIPAPI
-GdipGetMetafileHeaderFromStream(
- IStream * stream,
- MetafileHeader * header
- );
-
-GpStatus
-WINGDIPAPI
-GdipGetMetafileHeaderFromMetafile(
- GpMetafile * metafile,
- MetafileHeader * header
- );
-
-GpStatus
-WINGDIPAPI
-GdipGetHemfFromMetafile(
- GpMetafile * metafile,
- HENHMETAFILE * hEmf
- );
-
-GpStatus WINGDIPAPI
-GdipCreateStreamOnFile(GDIPCONST WCHAR * filename, UINT access, IStream **stream);
-
-GpStatus WINGDIPAPI
-GdipCreateMetafileFromWmf(HMETAFILE hWmf, BOOL deleteWmf,
- GDIPCONST APMFileHeader * apmFileHeader, GpMetafile **metafile);
-
-GpStatus WINGDIPAPI
-GdipCreateMetafileFromEmf(HENHMETAFILE hEmf, BOOL deleteEmf,
- GpMetafile **metafile);
-
-GpStatus WINGDIPAPI
-GdipCreateMetafileFromFile(GDIPCONST WCHAR* file, GpMetafile **metafile);
-
-GpStatus WINGDIPAPI
-GdipCreateMetafileFromWmfFile(GDIPCONST WCHAR* file, GDIPCONST APMFileHeader * apmFileHeader, GpMetafile **metafile);
-
-GpStatus WINGDIPAPI
-GdipCreateMetafileFromStream(IStream * stream, GpMetafile **metafile);
-
-GpStatus WINGDIPAPI
-GdipRecordMetafile(
- HDC referenceHdc,
- EmfType type,
- GDIPCONST GpRectF * frameRect,
- MetafileFrameUnit frameUnit,
- GDIPCONST WCHAR * description,
- GpMetafile ** metafile
- );
-
-GpStatus WINGDIPAPI
-GdipRecordMetafileI(
- HDC referenceHdc,
- EmfType type,
- GDIPCONST GpRect * frameRect,
- MetafileFrameUnit frameUnit,
- GDIPCONST WCHAR * description,
- GpMetafile ** metafile
- );
-
-GpStatus WINGDIPAPI
-GdipRecordMetafileFileName(
- GDIPCONST WCHAR* fileName,
- HDC referenceHdc,
- EmfType type,
- GDIPCONST GpRectF * frameRect,
- MetafileFrameUnit frameUnit,
- GDIPCONST WCHAR * description,
- GpMetafile ** metafile
- );
-
-GpStatus WINGDIPAPI
-GdipRecordMetafileFileNameI(
- GDIPCONST WCHAR* fileName,
- HDC referenceHdc,
- EmfType type,
- GDIPCONST GpRect * frameRect,
- MetafileFrameUnit frameUnit,
- GDIPCONST WCHAR * description,
- GpMetafile ** metafile
- );
-
-GpStatus WINGDIPAPI
-GdipRecordMetafileStream(
- IStream * stream,
- HDC referenceHdc,
- EmfType type,
- GDIPCONST GpRectF * frameRect,
- MetafileFrameUnit frameUnit,
- GDIPCONST WCHAR * description,
- GpMetafile ** metafile
- );
-
-GpStatus WINGDIPAPI
-GdipRecordMetafileStreamI(
- IStream * stream,
- HDC referenceHdc,
- EmfType type,
- GDIPCONST GpRect * frameRect,
- MetafileFrameUnit frameUnit,
- GDIPCONST WCHAR * description,
- GpMetafile ** metafile
- );
-
-GpStatus WINGDIPAPI
-GdipSetMetafileDownLevelRasterizationLimit(
- GpMetafile * metafile,
- UINT metafileRasterizationLimitDpi
- );
-
-GpStatus WINGDIPAPI
-GdipGetMetafileDownLevelRasterizationLimit(
- GDIPCONST GpMetafile * metafile,
- UINT * metafileRasterizationLimitDpi
- );
-
-GpStatus WINGDIPAPI
-GdipGetImageDecodersSize(UINT *numDecoders, UINT *size);
-
-GpStatus WINGDIPAPI
-GdipGetImageDecoders(UINT numDecoders,
- UINT size,
- ImageCodecInfo *decoders);
-
-GpStatus WINGDIPAPI
-GdipGetImageEncodersSize(UINT *numEncoders, UINT *size);
-
-GpStatus WINGDIPAPI
-GdipGetImageEncoders(UINT numEncoders,
- UINT size,
- ImageCodecInfo *encoders);
-
-GpStatus WINGDIPAPI
-GdipAddImageCodec(GDIPCONST ImageCodecInfo *codec);
-
-GpStatus WINGDIPAPI
-GdipRemoveImageCodec(GDIPCONST ImageCodecInfo *codec);
-
-#ifndef DCR_USE_NEW_186091
-GpStatus WINGDIPAPI
-GdipGetGraphicsPixel(GpGraphics* graphics, REAL x, REAL y, ARGB* argb);
-#endif
-
-GpStatus WINGDIPAPI
-GdipComment(GpGraphics* graphics, UINT sizeData, GDIPCONST BYTE * data);
-
-GpStatus WINGDIPAPI
-GdipGetGraphicsLayout(GpGraphics* graphics, GraphicsLayout* layout);
-
-GpStatus WINGDIPAPI
-GdipSetGraphicsLayout(GpGraphics* graphics, GDIPCONST GraphicsLayout layout);
-
-//----------------------------------------------------------------------------
-// FontFamily
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
- GpFontCollection *fontCollection,
- GpFontFamily **FontFamily);
-
-GpStatus WINGDIPAPI
-GdipDeleteFontFamily(GpFontFamily *FontFamily);
-
-GpStatus WINGDIPAPI
-GdipCloneFontFamily(GpFontFamily *FontFamily, GpFontFamily **clonedFontFamily);
-
-GpStatus WINGDIPAPI
-GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamily);
-
-GpStatus WINGDIPAPI
-GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily);
-
-GpStatus WINGDIPAPI
-GdipGetGenericFontFamilyMonospace(GpFontFamily **nativeFamily);
-
-
-GpStatus WINGDIPAPI
-GdipGetFamilyName(
- GDIPCONST GpFontFamily *family,
- WCHAR name[LF_FACESIZE],
- LANGID language
-);
-
-GpStatus WINGDIPAPI
-GdipIsStyleAvailable(GDIPCONST GpFontFamily *family, INT style, BOOL * IsStyleAvailable);
-
-GpStatus WINGDIPAPI
-GdipFontCollectionEnumerable(
- GpFontCollection* fontCollection,
- GpGraphics* graphics,
- INT * numFound
-);
-
-GpStatus WINGDIPAPI GdipFontCollectionEnumerate(
- GpFontCollection* fontCollection,
- INT numSought,
- GpFontFamily* gpfamilies[],
- INT* numFound,
- GpGraphics* graphics
-);
-
-//-----------------------------------
-// New API
-//-----------------------------------
-
-GpStatus WINGDIPAPI
-GdipGetEmHeight(GDIPCONST GpFontFamily *family, INT style, UINT16 * EmHeight);
-
-GpStatus WINGDIPAPI
-GdipGetCellAscent(GDIPCONST GpFontFamily *family, INT style, UINT16 * CellAscent);
-
-GpStatus WINGDIPAPI
-GdipGetCellDescent(GDIPCONST GpFontFamily *family, INT style, UINT16 * CellDescent);
-
-GpStatus WINGDIPAPI
-GdipGetLineSpacing(GDIPCONST GpFontFamily *family, INT style, UINT16 * LineSpacing);
-
-
-//----------------------------------------------------------------------------
-// Font
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateFontFromDC(
- HDC hdc,
- GpFont **font
-);
-
-GpStatus WINGDIPAPI
-GdipCreateFontFromLogfontA(
- HDC hdc,
- GDIPCONST LOGFONTA *logfont,
- GpFont **font
-);
-
-GpStatus WINGDIPAPI
-GdipCreateFontFromLogfontW(
- HDC hdc,
- GDIPCONST LOGFONTW *logfont,
- GpFont **font
-);
-
-GpStatus WINGDIPAPI
-GdipCreateFont(
- GDIPCONST GpFontFamily *fontFamily,
- REAL emSize,
- INT style,
- Unit unit,
- GpFont **font
-);
-
-GpStatus WINGDIPAPI
-GdipCloneFont(GpFont* font, GpFont** cloneFont);
-
-GpStatus WINGDIPAPI
-GdipDeleteFont(GpFont* font);
-
-GpStatus WINGDIPAPI
-GdipGetFamily(GpFont *font, GpFontFamily **family);
-
-GpStatus WINGDIPAPI
-GdipGetFontStyle(GpFont *font, INT *style);
-
-GpStatus WINGDIPAPI
-GdipGetFontSize(GpFont *font, REAL *size);
-
-GpStatus WINGDIPAPI
-GdipGetFontUnit(GpFont *font, Unit *unit);
-
-GpStatus WINGDIPAPI
-GdipGetFontHeight(GDIPCONST GpFont *font, GDIPCONST GpGraphics *graphics, REAL *height);
-
-#ifdef DCR_USE_NEW_125467
-GpStatus WINGDIPAPI
-GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi, REAL *height);
-#endif
-
-GpStatus WINGDIPAPI
-GdipGetLogFontA(GpFont * font, GpGraphics *graphics, LOGFONTA * logfontA);
-
-GpStatus WINGDIPAPI
-GdipGetLogFontW(GpFont * font, GpGraphics *graphics, LOGFONTW * logfontW);
-
-// FontCollection
-
-GpStatus WINGDIPAPI
-GdipNewInstalledFontCollection(GpFontCollection** fontCollection);
-
-GpStatus WINGDIPAPI
-GdipNewPrivateFontCollection(GpFontCollection** fontCollection);
-
-GpStatus WINGDIPAPI
-GdipDeletePrivateFontCollection(GpFontCollection** fontCollection);
-
-GpStatus WINGDIPAPI
-GdipGetFontCollectionFamilyCount(
- GpFontCollection* fontCollection,
- INT * numFound
-);
-
-GpStatus WINGDIPAPI
-GdipGetFontCollectionFamilyList(
- GpFontCollection* fontCollection,
- INT numSought,
- GpFontFamily* gpfamilies[],
- INT* numFound
-);
-
-#ifndef DCR_USE_NEW_235072
-GpStatus WINGDIPAPI
-GdipInstallFontFile(
- GpFontCollection* fontCollection,
- GDIPCONST WCHAR* filename
-);
-
-GpStatus WINGDIPAPI
-GdipUninstallFontFile(
- GpFontCollection* fontCollection,
- GDIPCONST WCHAR* filename
-);
-#endif
-
-GpStatus WINGDIPAPI
-GdipPrivateAddFontFile(
- GpFontCollection* fontCollection,
- GDIPCONST WCHAR* filename
-);
-
-GpStatus WINGDIPAPI
-GdipPrivateAddMemoryFont(
- GpFontCollection* fontCollection,
- GDIPCONST void* memory,
- INT length
-);
-
-//----------------------------------------------------------------------------
-// Text
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipDrawString(
- GpGraphics *graphics,
- GDIPCONST WCHAR *string,
- INT length,
- GDIPCONST GpFont *font,
- GDIPCONST RectF *layoutRect,
- GDIPCONST GpStringFormat *stringFormat,
- GDIPCONST GpBrush *brush
-);
-
-GpStatus WINGDIPAPI
-GdipMeasureString(
- GpGraphics *graphics,
- GDIPCONST WCHAR *string,
- INT length,
- GDIPCONST GpFont *font,
- GDIPCONST RectF *layoutRect,
- GDIPCONST GpStringFormat *stringFormat,
- RectF *boundingBox,
- INT *codepointsFitted,
- INT *linesFilled
-);
-
-#ifndef DCR_USE_NEW_174340
-GpStatus WINGDIPAPI
-GdipMeasureStringRegion(
- GpGraphics *graphics,
- GDIPCONST WCHAR *string,
- INT length,
- GDIPCONST GpFont *font,
- GDIPCONST RectF &layoutRect,
- GDIPCONST GpStringFormat *stringFormat,
- INT firstCharacterIndex,
- INT characterCount,
- GpRegion *region
-);
-#endif
-
-#ifdef DCR_USE_NEW_174340
-GpStatus
-WINGDIPAPI
-GdipMeasureCharacterRanges(
- GpGraphics *graphics,
- GDIPCONST WCHAR *string,
- INT length,
- GDIPCONST GpFont *font,
- GDIPCONST RectF &layoutRect,
- GDIPCONST GpStringFormat *stringFormat,
- INT regionCount,
- GpRegion **regions
-);
-#endif
-
-GpStatus WINGDIPAPI
-GdipDrawDriverString(
- GpGraphics *graphics,
- GDIPCONST UINT16 *text,
- INT length,
- GDIPCONST GpFont *font,
- GDIPCONST GpBrush *brush,
- GDIPCONST PointF *positions,
- INT flags,
- GDIPCONST GpMatrix *matrix
-);
-
-GpStatus WINGDIPAPI
-GdipMeasureDriverString(
- GpGraphics *graphics,
- GDIPCONST UINT16 *text,
- INT length,
- GDIPCONST GpFont *font,
- GDIPCONST PointF *positions,
- INT flags,
- GDIPCONST GpMatrix *matrix,
- RectF *boundingBox
-);
-
-#ifndef DCR_USE_NEW_168772
-GpStatus WINGDIPAPI
-GdipDriverStringPointToCodepoint(
- GpGraphics *graphics,
- GDIPCONST UINT16 *text,
- INT length,
- GDIPCONST GpFont *font,
- GDIPCONST PointF *positions,
- INT flags,
- GpMatrix *matrix,
- GDIPCONST PointF *hit,
- INT *index,
- BOOL *rightEdge,
- REAL *distance
-);
-#endif
-
-//----------------------------------------------------------------------------
-// String format APIs
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateStringFormat(
- INT formatAttributes,
- LANGID language,
- GpStringFormat **format
-);
-
-GpStatus WINGDIPAPI
-GdipStringFormatGetGenericDefault(GpStringFormat **format);
-
-GpStatus WINGDIPAPI
-GdipStringFormatGetGenericTypographic(GpStringFormat **format);
-
-GpStatus WINGDIPAPI
-GdipDeleteStringFormat(GpStringFormat *format);
-
-GpStatus WINGDIPAPI
-GdipCloneStringFormat(GDIPCONST GpStringFormat *format, GpStringFormat **newFormat);
-
-GpStatus WINGDIPAPI
-GdipSetStringFormatFlags(GpStringFormat *format, INT flags);
-
-GpStatus WINGDIPAPI GdipGetStringFormatFlags(GDIPCONST GpStringFormat *format, INT *flags);
-
-#ifndef DCR_USE_NEW_152154
-GpStatus WINGDIPAPI
-GdipSetStringFormatLineSpacing(GpStringFormat *format, REAL amount,
- LineSpacing method);
-
-GpStatus WINGDIPAPI
-GdipGetStringFormatLineSpacingAmount(GDIPCONST GpStringFormat *format, REAL *amount);
-GpStatus WINGDIPAPI
-GdipGetStringFormatLineSpacingMethod(GDIPCONST GpStringFormat *format, LineSpacing *method);
-#endif
-
-GpStatus WINGDIPAPI
-GdipSetStringFormatAlign(GpStringFormat *format, StringAlignment align);
-
-GpStatus WINGDIPAPI
-GdipGetStringFormatAlign(GDIPCONST GpStringFormat *format, StringAlignment *align);
-
-GpStatus WINGDIPAPI
-GdipSetStringFormatLineAlign(GpStringFormat *format,
- StringAlignment align);
-
-GpStatus WINGDIPAPI
-GdipGetStringFormatLineAlign(GDIPCONST GpStringFormat *format,
- StringAlignment *align);
-
-GpStatus WINGDIPAPI
-GdipSetStringFormatTrimming(
- GpStringFormat *format,
- StringTrimming trimming
-);
-
-GpStatus WINGDIPAPI
-GdipGetStringFormatTrimming(
- GDIPCONST GpStringFormat *format,
- StringTrimming *trimming
-);
-
-GpStatus WINGDIPAPI
-GdipSetStringFormatHotkeyPrefix(GpStringFormat *format, INT hotkeyPrefix);
-
-GpStatus WINGDIPAPI
-GdipGetStringFormatHotkeyPrefix(GDIPCONST GpStringFormat *format, INT *hotkeyPrefix);
-
-GpStatus WINGDIPAPI
-GdipSetStringFormatTabStops(GpStringFormat *format, REAL firstTabOffset, INT count, GDIPCONST REAL *tabStops);
-
-GpStatus WINGDIPAPI
-GdipGetStringFormatTabStops(GDIPCONST GpStringFormat *format, INT count, REAL *firstTabOffset, REAL *tabStops);
-
-GpStatus WINGDIPAPI
-GdipGetStringFormatTabStopCount(GDIPCONST GpStringFormat *format, INT * count);
-
-#ifdef DCR_USE_NEW_146933
-GpStatus WINGDIPAPI
-GdipSetStringFormatDigitSubstitution(GpStringFormat *format, LANGID language,
- StringDigitSubstitute substitute);
-
-GpStatus WINGDIPAPI
-GdipGetStringFormatDigitSubstitution(GDIPCONST GpStringFormat *format, LANGID *language,
- StringDigitSubstitute *substitute);
-#endif // DCR_USE_NEW_146933
-
-#ifdef DCR_USE_NEW_174340
-GpStatus WINGDIPAPI
-GdipGetStringFormatMeasurableCharacterRangeCount(
- GDIPCONST GpStringFormat *format,
- INT *count
-);
-
-GpStatus WINGDIPAPI
-GdipSetStringFormatMeasurableCharacterRanges(
- GpStringFormat *format,
- INT rangeCount,
- GDIPCONST CharacterRange *ranges
-);
-#endif
-
-//----------------------------------------------------------------------------
-// Cached Bitmap APIs
-//----------------------------------------------------------------------------
-
-GpStatus WINGDIPAPI
-GdipCreateCachedBitmap(
- GpBitmap *bitmap,
- GpGraphics *graphics,
- GpCachedBitmap **cachedBitmap
-);
-
-GpStatus WINGDIPAPI
-GdipDeleteCachedBitmap(GpCachedBitmap *cachedBitmap);
-
-GpStatus WINGDIPAPI
-GdipDrawCachedBitmap(
- GpGraphics *graphics,
- GpCachedBitmap *cachedBitmap,
- INT x,
- INT y
-);
-
-UINT WINGDIPAPI
-GdipEmfToWmfBits(
- HENHMETAFILE hemf,
- UINT cbData16,
- LPBYTE pData16,
- INT iMapMode,
- INT eFlags
-);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // !_FLATAPI_H
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusFlat.h
+*
+* Abstract:
+*
+* Flat GDI+ API wrappers - header file
+*
+\**************************************************************************/
+
+// TODO: this file style needs to be made internally consistent with the way
+// it handles breaking the long argument lists across multiple lines
+
+#ifndef _FLATAPI_H
+#define _FLATAPI_H
+
+#define WINGDIPAPI __stdcall
+
+// currently, only C++ wrapper API's force const.
+
+#define GDIPCONST const
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef DCR_USE_NEW_175866
+
+VOID
+WINGDIPAPI
+GdipDisplayPaletteWindowNotify(WindowNotifyEnum notify);
+
+#endif
+
+//----------------------------------------------------------------------------
+// GraphicsPath methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreatePath(GpFillMode brushMode, GpPath **path);
+
+GpStatus WINGDIPAPI
+GdipCreatePath2(GDIPCONST GpPointF*, GDIPCONST BYTE*, INT, GpFillMode,
+ GpPath **path);
+
+GpStatus WINGDIPAPI
+GdipCreatePath2I(GDIPCONST GpPoint*, GDIPCONST BYTE*, INT, GpFillMode,
+ GpPath **path);
+
+GpStatus WINGDIPAPI
+GdipClonePath(GpPath* path, GpPath **clonePath);
+
+GpStatus WINGDIPAPI
+GdipDeletePath(GpPath* path);
+
+GpStatus WINGDIPAPI
+GdipResetPath(GpPath* path);
+
+GpStatus WINGDIPAPI
+GdipGetPointCount(GpPath* path, INT* count);
+
+GpStatus WINGDIPAPI
+GdipGetPathTypes(GpPath* path, BYTE* types, INT count);
+
+GpStatus WINGDIPAPI
+GdipGetPathPoints(GpPath*, GpPointF* points, INT count);
+
+GpStatus WINGDIPAPI
+GdipGetPathPointsI(GpPath*, GpPoint* points, INT count);
+
+GpStatus WINGDIPAPI
+GdipGetPathFillMode(GpPath *path, GpFillMode *fillmode);
+
+GpStatus WINGDIPAPI
+GdipSetPathFillMode(GpPath *path, GpFillMode fillmode);
+
+GpStatus WINGDIPAPI
+GdipGetPathData(GpPath *path, GpPathData* pathData);
+
+GpStatus WINGDIPAPI
+GdipStartPathFigure(GpPath *path);
+
+GpStatus WINGDIPAPI
+GdipClosePathFigure(GpPath *path);
+
+GpStatus WINGDIPAPI
+GdipClosePathFigures(GpPath *path);
+
+GpStatus WINGDIPAPI
+GdipSetPathMarker(GpPath* path);
+
+GpStatus WINGDIPAPI
+GdipClearPathMarkers(GpPath* path);
+
+GpStatus WINGDIPAPI
+GdipReversePath(GpPath* path);
+
+GpStatus WINGDIPAPI
+GdipGetPathLastPoint(GpPath* path, GpPointF* lastPoint);
+
+GpStatus WINGDIPAPI
+GdipAddPathLine(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2);
+
+GpStatus WINGDIPAPI
+GdipAddPathLine2(GpPath *path, GDIPCONST GpPointF *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathArc(GpPath *path, REAL x, REAL y, REAL width, REAL height,
+ REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipAddPathBezier(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2,
+ REAL x3, REAL y3, REAL x4, REAL y4);
+
+GpStatus WINGDIPAPI
+GdipAddPathBeziers(GpPath *path, GDIPCONST GpPointF *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathCurve(GpPath *path, GDIPCONST GpPointF *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count,
+ REAL tension);
+
+GpStatus WINGDIPAPI
+GdipAddPathCurve3(GpPath *path, GDIPCONST GpPointF *points, INT count,
+ INT offset, INT numberOfSegments, REAL tension);
+
+GpStatus WINGDIPAPI
+GdipAddPathClosedCurve(GpPath *path, GDIPCONST GpPointF *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathClosedCurve2(GpPath *path, GDIPCONST GpPointF *points, INT count,
+ REAL tension);
+
+GpStatus WINGDIPAPI
+GdipAddPathRectangle(GpPath *path, REAL x, REAL y, REAL width, REAL height);
+
+GpStatus WINGDIPAPI
+GdipAddPathRectangles(GpPath *path, GDIPCONST GpRectF *rects, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathEllipse(GpPath *path, REAL x, REAL y, REAL width,
+ REAL height);
+
+GpStatus WINGDIPAPI
+GdipAddPathPie(GpPath *path, REAL x, REAL y, REAL width, REAL height,
+ REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipAddPathPolygon(GpPath *path, GDIPCONST GpPointF *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathPath(GpPath *path, GDIPCONST GpPath* addingPath, BOOL connect);
+
+GpStatus WINGDIPAPI
+GdipAddPathString(GpPath *path, GDIPCONST WCHAR *string,
+ INT length, GDIPCONST GpFontFamily *family, INT style,
+ REAL emSize, GDIPCONST RectF *layoutRect,
+ GDIPCONST GpStringFormat *format);
+
+GpStatus WINGDIPAPI
+GdipAddPathStringI(GpPath *path, GDIPCONST WCHAR *string,
+ INT length, GDIPCONST GpFontFamily *family, INT style,
+ REAL emSize, GDIPCONST Rect *layoutRect,
+ GDIPCONST GpStringFormat *format);
+
+GpStatus WINGDIPAPI
+GdipAddPathLineI(GpPath *path, INT x1, INT y1, INT x2, INT y2);
+
+GpStatus WINGDIPAPI
+GdipAddPathLine2I(GpPath *path, GDIPCONST GpPoint *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathArcI(GpPath *path, INT x, INT y, INT width, INT height,
+ REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipAddPathBezierI(GpPath *path, INT x1, INT y1, INT x2, INT y2,
+ INT x3, INT y3, INT x4, INT y4);
+
+GpStatus WINGDIPAPI
+GdipAddPathBeziersI(GpPath *path, GDIPCONST GpPoint *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathCurveI(GpPath *path, GDIPCONST GpPoint *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathCurve2I(GpPath *path, GDIPCONST GpPoint *points, INT count,
+ REAL tension);
+
+GpStatus WINGDIPAPI
+GdipAddPathCurve3I(GpPath *path, GDIPCONST GpPoint *points, INT count,
+ INT offset, INT numberOfSegments, REAL tension);
+
+GpStatus WINGDIPAPI
+GdipAddPathClosedCurveI(GpPath *path, GDIPCONST GpPoint *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathClosedCurve2I(GpPath *path, GDIPCONST GpPoint *points, INT count,
+ REAL tension);
+
+GpStatus WINGDIPAPI
+GdipAddPathRectangleI(GpPath *path, INT x, INT y, INT width, INT height);
+
+GpStatus WINGDIPAPI
+GdipAddPathRectanglesI(GpPath *path, GDIPCONST GpRect *rects, INT count);
+
+GpStatus WINGDIPAPI
+GdipAddPathEllipseI(GpPath *path, INT x, INT y, INT width, INT height);
+
+GpStatus WINGDIPAPI
+GdipAddPathPieI(GpPath *path, INT x, INT y, INT width, INT height,
+ REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipAddPathPolygonI(GpPath *path, GDIPCONST GpPoint *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipFlattenPath(GpPath *path, GpMatrix* matrix, REAL flatness);
+
+GpStatus WINGDIPAPI
+GdipWindingModeOutline(
+ GpPath *path,
+ GpMatrix *matrix,
+ REAL flatness
+);
+
+
+#ifdef DCR_USE_NEW_202903
+
+GpStatus WINGDIPAPI
+GdipWidenPath(
+ GpPath *nativePath,
+ GpPen *pen,
+ GpMatrix *matrix,
+ REAL flatness
+);
+
+#else
+
+GpStatus WINGDIPAPI
+GdipWidenPathWithMinimumResolutions(GpPath *path, GpPen *pen, REAL minXres,
+ REAL minYres, GpMatrix *matrix, BOOL removeSelftIntersects);
+
+#endif
+
+GpStatus WINGDIPAPI
+GdipWarpPath(GpPath *path, GpMatrix* matrix,
+ GDIPCONST GpPointF *points, INT count,
+ REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight,
+ WarpMode warpMode, REAL flatness);
+
+GpStatus WINGDIPAPI
+GdipTransformPath(GpPath* path, GpMatrix* matrix);
+
+GpStatus WINGDIPAPI
+GdipGetPathWorldBounds(GpPath* path, GpRectF* bounds, GDIPCONST GpMatrix *matrix,
+ GDIPCONST GpPen *pen);
+
+GpStatus WINGDIPAPI
+GdipGetPathWorldBoundsI(GpPath* path, GpRect* bounds, GDIPCONST GpMatrix *matrix,
+ GDIPCONST GpPen *pen);
+
+GpStatus WINGDIPAPI
+GdipIsVisiblePathPoint(GpPath* path, REAL x, REAL y,
+ GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsVisiblePathPointI(GpPath* path, INT x, INT y,
+ GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsOutlineVisiblePathPoint(GpPath* path, REAL x, REAL y, GpPen *pen,
+ GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsOutlineVisiblePathPointI(GpPath* path, INT x, INT y, GpPen *pen,
+ GpGraphics *graphics, BOOL *result);
+
+
+//----------------------------------------------------------------------------
+// Path Enumeration methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreatePathIter(GpPathIterator **iterator, GpPath* path);
+
+GpStatus WINGDIPAPI
+GdipDeletePathIter(GpPathIterator *iterator);
+
+GpStatus WINGDIPAPI
+GdipPathIterNextSubpath(GpPathIterator* iterator, INT *resultCount,
+ INT* startIndex, INT* endIndex, BOOL* isClosed);
+
+GpStatus WINGDIPAPI
+GdipPathIterNextSubpathPath(GpPathIterator* iterator, INT* resultCount,
+ GpPath* path, BOOL* isClosed);
+
+GpStatus WINGDIPAPI
+GdipPathIterNextPathType(GpPathIterator* iterator, INT* resultCount,
+ BYTE* pathType, INT* startIndex, INT* endIndex);
+
+GpStatus WINGDIPAPI
+GdipPathIterNextMarker(GpPathIterator* iterator, INT *resultCount,
+ INT* startIndex, INT* endIndex);
+
+GpStatus WINGDIPAPI
+GdipPathIterNextMarkerPath(GpPathIterator* iterator, INT* resultCount,
+ GpPath* path);
+
+GpStatus WINGDIPAPI
+GdipPathIterGetCount(GpPathIterator* iterator, INT* count);
+
+GpStatus WINGDIPAPI
+GdipPathIterGetSubpathCount(GpPathIterator* iterator, INT* count);
+
+GpStatus WINGDIPAPI
+GdipPathIterIsValid(GpPathIterator* iterator, BOOL* valid);
+
+GpStatus WINGDIPAPI
+GdipPathIterHasCurve(GpPathIterator* iterator, BOOL* hasCurve);
+
+GpStatus WINGDIPAPI
+GdipPathIterRewind(GpPathIterator* iterator);
+
+GpStatus WINGDIPAPI
+GdipPathIterEnumerate(GpPathIterator* iterator, INT* resultCount,
+ GpPointF *points, BYTE *types, INT count);
+
+GpStatus WINGDIPAPI
+GdipPathIterCopyData(GpPathIterator* iterator, INT* resultCount,
+ GpPointF* points, BYTE* types, INT startIndex, INT endIndex);
+
+//----------------------------------------------------------------------------
+// Matrix methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateMatrix(GpMatrix **matrix);
+
+GpStatus WINGDIPAPI
+GdipCreateMatrix2(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx,
+ REAL dy, GpMatrix **matrix);
+
+GpStatus WINGDIPAPI
+GdipCreateMatrix3(GDIPCONST GpRectF *rect, GDIPCONST GpPointF *dstplg,
+ GpMatrix **matrix);
+
+GpStatus WINGDIPAPI
+GdipCreateMatrix3I(GDIPCONST GpRect *rect, GDIPCONST GpPoint *dstplg,
+ GpMatrix **matrix);
+
+GpStatus WINGDIPAPI
+GdipCloneMatrix(GpMatrix *matrix, GpMatrix **cloneMatrix);
+
+GpStatus WINGDIPAPI
+GdipDeleteMatrix(GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipSetMatrixElements(GpMatrix *matrix, REAL m11, REAL m12, REAL m21, REAL m22,
+ REAL dx, REAL dy);
+
+GpStatus WINGDIPAPI
+GdipMultiplyMatrix(GpMatrix *matrix, GpMatrix* matrix2,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipTranslateMatrix(GpMatrix *matrix, REAL offsetX, REAL offsetY,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipScaleMatrix(GpMatrix *matrix, REAL scaleX, REAL scaleY,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipRotateMatrix(GpMatrix *matrix, REAL angle, GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipShearMatrix(GpMatrix *matrix, REAL shearX, REAL shearY,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipInvertMatrix(GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts, INT count);
+
+GpStatus WINGDIPAPI
+GdipTransformMatrixPointsI(GpMatrix *matrix, GpPoint *pts, INT count);
+
+GpStatus WINGDIPAPI
+GdipVectorTransformMatrixPoints(GpMatrix *matrix, GpPointF *pts,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipVectorTransformMatrixPointsI(GpMatrix *matrix, GpPoint *pts,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipGetMatrixElements(GDIPCONST GpMatrix *matrix, REAL *matrixOut);
+
+GpStatus WINGDIPAPI
+GdipIsMatrixInvertible(GDIPCONST GpMatrix *matrix, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsMatrixIdentity(GDIPCONST GpMatrix *matrix, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsMatrixEqual(GDIPCONST GpMatrix *matrix, GDIPCONST GpMatrix *matrix2, BOOL *result);
+
+//----------------------------------------------------------------------------
+// Region methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateRegion(GpRegion **region);
+
+GpStatus WINGDIPAPI
+GdipCreateRegionRect(GDIPCONST GpRectF *rect, GpRegion **region);
+
+GpStatus WINGDIPAPI
+GdipCreateRegionRectI(GDIPCONST GpRect *rect, GpRegion **region);
+
+GpStatus WINGDIPAPI
+GdipCreateRegionPath(GpPath *path, GpRegion **region);
+
+GpStatus WINGDIPAPI
+GdipCreateRegionRgnData(GDIPCONST BYTE *regionData, INT size, GpRegion **region);
+
+GpStatus WINGDIPAPI
+GdipCreateRegionHrgn(HRGN hRgn, GpRegion **region);
+
+GpStatus WINGDIPAPI
+GdipCloneRegion(GpRegion *region, GpRegion **cloneRegion);
+
+GpStatus WINGDIPAPI
+GdipDeleteRegion(GpRegion *region);
+
+GpStatus WINGDIPAPI
+GdipSetInfinite(GpRegion *region);
+
+GpStatus WINGDIPAPI
+GdipSetEmpty(GpRegion *region);
+
+GpStatus WINGDIPAPI
+GdipCombineRegionRect(GpRegion *region, GDIPCONST GpRectF *rect,
+ CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipCombineRegionRectI(GpRegion *region, GDIPCONST GpRect *rect,
+ CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipCombineRegionPath(GpRegion *region, GpPath *path, CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipCombineRegionRegion(GpRegion *region, GpRegion *region2,
+ CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipTranslateRegion(GpRegion *region, REAL dx, REAL dy);
+
+GpStatus WINGDIPAPI
+GdipTranslateRegionI(GpRegion *region, INT dx, INT dy);
+
+GpStatus WINGDIPAPI
+GdipTransformRegion(GpRegion *region, GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipGetRegionBounds(GpRegion *region, GpGraphics *graphics,
+ GpRectF *rect);
+
+GpStatus WINGDIPAPI
+GdipGetRegionBoundsI(GpRegion *region, GpGraphics *graphics,
+ GpRect *rect);
+
+GpStatus WINGDIPAPI
+GdipGetRegionHRgn(GpRegion *region, GpGraphics *graphics, HRGN *hRgn);
+
+GpStatus WINGDIPAPI
+GdipIsEmptyRegion(GpRegion *region, GpGraphics *graphics,
+ BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsInfiniteRegion(GpRegion *region, GpGraphics *graphics,
+ BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsEqualRegion(GpRegion *region, GpRegion *region2,
+ GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipGetRegionDataSize(GpRegion *region, UINT * bufferSize);
+
+GpStatus WINGDIPAPI
+GdipGetRegionData(GpRegion *region, BYTE * buffer, UINT bufferSize, UINT * sizeFilled);
+
+GpStatus WINGDIPAPI
+GdipIsVisibleRegionPoint(GpRegion *region, REAL x, REAL y,
+ GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsVisibleRegionPointI(GpRegion *region, INT x, INT y,
+ GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsVisibleRegionRect(GpRegion *region, REAL x, REAL y, REAL width,
+ REAL height, GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsVisibleRegionRectI(GpRegion *region, INT x, INT y, INT width,
+ INT height, GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipGetRegionScansCount(GpRegion *region, UINT* count, GpMatrix* matrix);
+
+GpStatus WINGDIPAPI
+GdipGetRegionScans(GpRegion *region, GpRectF* rects, INT* count, GpMatrix* matrix);
+
+GpStatus WINGDIPAPI
+GdipGetRegionScansI(GpRegion *region, GpRect* rects, INT* count, GpMatrix* matrix);
+
+//----------------------------------------------------------------------------
+// Brush methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCloneBrush(GpBrush *brush, GpBrush **cloneBrush);
+
+GpStatus WINGDIPAPI
+GdipDeleteBrush(GpBrush *brush);
+
+GpStatus WINGDIPAPI
+GdipGetBrushType(GpBrush *brush, GpBrushType *type);
+
+//----------------------------------------------------------------------------
+// Hatch Brush methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateHatchBrush(GpHatchStyle hatchstyle, ARGB forecol,
+ ARGB backcol, GpHatch **brush);
+
+GpStatus WINGDIPAPI
+GdipGetHatchStyle(GpHatch *brush, GpHatchStyle *hatchstyle);
+
+GpStatus WINGDIPAPI
+GdipGetHatchForegroundColor(GpHatch *brush, ARGB* forecol);
+
+GpStatus WINGDIPAPI
+GdipGetHatchBackgroundColor(GpHatch *brush, ARGB* backcol);
+
+//----------------------------------------------------------------------------
+// Texture Brush methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateTexture(GpImage *image, GpWrapMode wrapmode,
+ GpTexture **texture);
+
+GpStatus WINGDIPAPI
+GdipCreateTexture2(GpImage *image, GpWrapMode wrapmode, REAL x,
+ REAL y, REAL width, REAL height, GpTexture **texture);
+
+GpStatus WINGDIPAPI
+GdipCreateTextureIA(GpImage *image, GDIPCONST GpImageAttributes *imageAttributes,
+ REAL x, REAL y, REAL width, REAL height,
+ GpTexture **texture);
+
+GpStatus WINGDIPAPI
+GdipCreateTexture2I(GpImage *image, GpWrapMode wrapmode, INT x,
+ INT y, INT width, INT height, GpTexture **texture);
+
+GpStatus WINGDIPAPI
+GdipCreateTextureIAI(GpImage *image, GDIPCONST GpImageAttributes *imageAttributes,
+ INT x, INT y, INT width, INT height,
+ GpTexture **texture);
+
+
+GpStatus WINGDIPAPI
+GdipGetTextureTransform(GpTexture *brush, GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipSetTextureTransform(GpTexture *brush, GDIPCONST GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipResetTextureTransform(GpTexture* brush);
+
+GpStatus WINGDIPAPI
+GdipMultiplyTextureTransform(GpTexture* brush, GDIPCONST GpMatrix *matrix,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipTranslateTextureTransform(GpTexture* brush, REAL dx, REAL dy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipScaleTextureTransform(GpTexture* brush, REAL sx, REAL sy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipRotateTextureTransform(GpTexture* brush, REAL angle, GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipSetTextureWrapMode(GpTexture *brush, GpWrapMode wrapmode);
+
+GpStatus WINGDIPAPI
+GdipGetTextureWrapMode(GpTexture *brush, GpWrapMode *wrapmode);
+
+GpStatus WINGDIPAPI
+GdipGetTextureImage(GpTexture *brush, GpImage **image);
+
+//----------------------------------------------------------------------------
+// Solid Brush methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateSolidFill(ARGB color, GpSolidFill **brush);
+
+GpStatus WINGDIPAPI
+GdipSetSolidFillColor(GpSolidFill *brush, ARGB color);
+
+GpStatus WINGDIPAPI
+GdipGetSolidFillColor(GpSolidFill *brush, ARGB *color);
+
+//----------------------------------------------------------------------------
+// LineBrush methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateLineBrush(GDIPCONST GpPointF* point1,
+ GDIPCONST GpPointF* point2,
+ ARGB color1, ARGB color2,
+ GpWrapMode wrapMode,
+ GpLineGradient **lineGradient);
+
+GpStatus WINGDIPAPI
+GdipCreateLineBrushI(GDIPCONST GpPoint* point1,
+ GDIPCONST GpPoint* point2,
+ ARGB color1, ARGB color2,
+ GpWrapMode wrapMode,
+ GpLineGradient **lineGradient);
+
+GpStatus WINGDIPAPI
+GdipCreateLineBrushFromRect(GDIPCONST GpRectF* rect,
+ ARGB color1, ARGB color2,
+ LinearGradientMode mode,
+ GpWrapMode wrapMode,
+ GpLineGradient **lineGradient);
+
+GpStatus WINGDIPAPI
+GdipCreateLineBrushFromRectI(GDIPCONST GpRect* rect,
+ ARGB color1, ARGB color2,
+ LinearGradientMode mode,
+ GpWrapMode wrapMode,
+ GpLineGradient **lineGradient);
+
+GpStatus WINGDIPAPI
+GdipCreateLineBrushFromRectWithAngle(GDIPCONST GpRectF* rect,
+ ARGB color1, ARGB color2,
+ REAL angle,
+ BOOL isAngleScalable,
+ GpWrapMode wrapMode,
+ GpLineGradient **lineGradient);
+
+GpStatus WINGDIPAPI
+GdipCreateLineBrushFromRectWithAngleI(GDIPCONST GpRect* rect,
+ ARGB color1, ARGB color2,
+ REAL angle,
+ BOOL isAngleScalable,
+ GpWrapMode wrapMode,
+ GpLineGradient **lineGradient);
+
+GpStatus WINGDIPAPI
+GdipSetLinePoints(GpLineGradient *brush,
+ GDIPCONST GpPointF* point1,
+ GDIPCONST GpPointF* point2);
+
+GpStatus WINGDIPAPI
+GdipSetLinePointsI(GpLineGradient *brush,
+ GDIPCONST GpPoint* point1,
+ GDIPCONST GpPoint* point2);
+
+GpStatus WINGDIPAPI
+GdipGetLinePoints(GpLineGradient *brush, GpPointF* points);
+
+GpStatus WINGDIPAPI
+GdipGetLinePointsI(GpLineGradient *brush, GpPoint* points);
+
+GpStatus WINGDIPAPI
+GdipSetLineColors(GpLineGradient *brush, ARGB color1, ARGB color2);
+
+GpStatus WINGDIPAPI
+GdipGetLineColors(GpLineGradient *brush, ARGB* colors);
+
+GpStatus WINGDIPAPI
+GdipGetLineRect(GpLineGradient *brush, GpRectF *rect);
+
+GpStatus WINGDIPAPI
+GdipGetLineRectI(GpLineGradient *brush, GpRect *rect);
+
+GpStatus WINGDIPAPI
+GdipSetLineGammaCorrection(GpLineGradient *brush, BOOL useGammaCorrection);
+
+GpStatus WINGDIPAPI
+GdipGetLineGammaCorrection(GpLineGradient *brush, BOOL *useGammaCorrection);
+
+GpStatus WINGDIPAPI
+GdipGetLineBlendCount(GpLineGradient *brush, INT *count);
+
+GpStatus WINGDIPAPI
+GdipGetLineBlend(GpLineGradient *brush, REAL *blend, REAL* positions,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipSetLineBlend(GpLineGradient *brush, GDIPCONST REAL *blend,
+ GDIPCONST REAL* positions, INT count);
+
+GpStatus WINGDIPAPI
+GdipGetLinePresetBlendCount(GpLineGradient *brush, INT *count);
+
+GpStatus WINGDIPAPI
+GdipGetLinePresetBlend(GpLineGradient *brush, ARGB *blend,
+ REAL* positions, INT count);
+
+GpStatus WINGDIPAPI
+GdipSetLinePresetBlend(GpLineGradient *brush, GDIPCONST ARGB *blend,
+ GDIPCONST REAL* positions, INT count);
+
+GpStatus WINGDIPAPI
+GdipSetLineSigmaBlend(GpLineGradient *brush, REAL focus, REAL scale);
+
+GpStatus WINGDIPAPI
+GdipSetLineLinearBlend(GpLineGradient *brush, REAL focus, REAL scale);
+
+GpStatus WINGDIPAPI
+GdipSetLineWrapMode(GpLineGradient *brush, GpWrapMode wrapmode);
+
+GpStatus WINGDIPAPI
+GdipGetLineWrapMode(GpLineGradient *brush, GpWrapMode *wrapmode);
+
+GpStatus WINGDIPAPI
+GdipGetLineTransform(GpLineGradient *brush, GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipSetLineTransform(GpLineGradient *brush, GDIPCONST GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipResetLineTransform(GpLineGradient* brush);
+
+GpStatus WINGDIPAPI
+GdipMultiplyLineTransform(GpLineGradient* brush, GDIPCONST GpMatrix *matrix,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipTranslateLineTransform(GpLineGradient* brush, REAL dx, REAL dy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipScaleLineTransform(GpLineGradient* brush, REAL sx, REAL sy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipRotateLineTransform(GpLineGradient* brush, REAL angle, GpMatrixOrder order);
+
+//----------------------------------------------------------------------------
+// PathGradient Brush
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreatePathGradient(GDIPCONST GpPointF* points,
+ INT count,
+ GpWrapMode wrapMode,
+ GpPathGradient **polyGradient);
+
+GpStatus WINGDIPAPI
+GdipCreatePathGradientI(GDIPCONST GpPoint* points,
+ INT count,
+ GpWrapMode wrapMode,
+ GpPathGradient **polyGradient);
+
+GpStatus WINGDIPAPI
+GdipCreatePathGradientFromPath(GDIPCONST GpPath* path,
+ GpPathGradient **polyGradient);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientCenterColor(
+ GpPathGradient *brush, ARGB* colors);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientCenterColor(
+ GpPathGradient *brush, ARGB colors);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientSurroundColorsWithCount(
+ GpPathGradient *brush, ARGB* color, INT* count);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientSurroundColorsWithCount(
+ GpPathGradient *brush,
+ GDIPCONST ARGB* color, INT* count);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientPath(GpPathGradient *brush, GpPath *path);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientPath(GpPathGradient *brush, GDIPCONST GpPath *path);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientCenterPoint(
+ GpPathGradient *brush, GpPointF* points);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientCenterPointI(
+ GpPathGradient *brush, GpPoint* points);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientCenterPoint(
+ GpPathGradient *brush, GDIPCONST GpPointF* points);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientCenterPointI(
+ GpPathGradient *brush, GDIPCONST GpPoint* points);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientRect(GpPathGradient *brush, GpRectF *rect);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientRectI(GpPathGradient *brush, GpRect *rect);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientPointCount(GpPathGradient *brush, INT* count);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientSurroundColorCount(GpPathGradient *brush, INT* count);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientGammaCorrection(GpPathGradient *brush, BOOL useGammaCorrection);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientGammaCorrection(GpPathGradient *brush, BOOL *useGammaCorrection);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientBlendCount(GpPathGradient *brush,
+ INT *count);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientBlend(GpPathGradient *brush,
+ REAL *blend, REAL *positions, INT count);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientBlend(GpPathGradient *brush,
+ GDIPCONST REAL *blend, GDIPCONST REAL *positions, INT count);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientPresetBlendCount(GpPathGradient *brush, INT *count);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientPresetBlend(GpPathGradient *brush, ARGB *blend,
+ REAL* positions, INT count);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientPresetBlend(GpPathGradient *brush, GDIPCONST ARGB *blend,
+ GDIPCONST REAL* positions, INT count);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientSigmaBlend(GpPathGradient *brush, REAL focus, REAL scale);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientLinearBlend(GpPathGradient *brush, REAL focus, REAL scale);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientWrapMode(GpPathGradient *brush,
+ GpWrapMode *wrapmode);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientWrapMode(GpPathGradient *brush,
+ GpWrapMode wrapmode);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientTransform(GpPathGradient *brush,
+ GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientTransform(GpPathGradient *brush,
+ GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipResetPathGradientTransform(GpPathGradient* brush);
+
+GpStatus WINGDIPAPI
+GdipMultiplyPathGradientTransform(GpPathGradient* brush, GDIPCONST GpMatrix *matrix,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipTranslatePathGradientTransform(GpPathGradient* brush, REAL dx, REAL dy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipScalePathGradientTransform(GpPathGradient* brush, REAL sx, REAL sy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipRotatePathGradientTransform(GpPathGradient* brush, REAL angle,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipGetPathGradientFocusScales(GpPathGradient *brush, REAL* xScale, REAL* yScale);
+
+GpStatus WINGDIPAPI
+GdipSetPathGradientFocusScales(GpPathGradient *brush, REAL xScale, REAL yScale);
+
+//----------------------------------------------------------------------------
+// Pen methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreatePen1(ARGB color, REAL width, GpUnit unit, GpPen **pen);
+
+GpStatus WINGDIPAPI
+GdipCreatePen2(GpBrush *brush, REAL width, GpUnit unit,
+ GpPen **pen);
+
+GpStatus WINGDIPAPI
+GdipClonePen(GpPen *pen, GpPen **clonepen);
+
+GpStatus WINGDIPAPI
+GdipDeletePen(GpPen *pen);
+
+GpStatus WINGDIPAPI
+GdipSetPenWidth(GpPen *pen, REAL width);
+
+GpStatus WINGDIPAPI
+GdipGetPenWidth(GpPen *pen, REAL *width);
+
+GpStatus WINGDIPAPI
+GdipSetPenUnit(GpPen *pen, GpUnit unit);
+
+GpStatus WINGDIPAPI
+GdipGetPenUnit(GpPen *pen, GpUnit *unit);
+
+#ifdef DCR_USE_NEW_197819
+GpStatus WINGDIPAPI
+GdipSetPenLineCap197819(GpPen *pen, GpLineCap startCap, GpLineCap endCap,
+ GpDashCap dashCap);
+#else
+GpStatus WINGDIPAPI
+GdipSetPenLineCap(GpPen *pen, GpLineCap startCap, GpLineCap endCap,
+ GpLineCap dashCap);
+#endif // DCR_USE_NEW_197819
+
+
+GpStatus WINGDIPAPI
+GdipSetPenStartCap(GpPen *pen, GpLineCap startCap);
+
+GpStatus WINGDIPAPI
+GdipSetPenEndCap(GpPen *pen, GpLineCap endCap);
+
+#ifdef DCR_USE_NEW_197819
+GpStatus WINGDIPAPI
+GdipSetPenDashCap197819(GpPen *pen, GpDashCap dashCap);
+#else
+GpStatus WINGDIPAPI
+GdipSetPenDashCap(GpPen *pen, GpLineCap dashCap);
+#endif // DCR_USE_NEW_197819
+
+GpStatus WINGDIPAPI
+GdipGetPenStartCap(GpPen *pen, GpLineCap *startCap);
+
+GpStatus WINGDIPAPI
+GdipGetPenEndCap(GpPen *pen, GpLineCap *endCap);
+
+#ifdef DCR_USE_NEW_197819
+GpStatus WINGDIPAPI
+GdipGetPenDashCap197819(GpPen *pen, GpDashCap *dashCap);
+#else
+GpStatus WINGDIPAPI
+GdipGetPenDashCap(GpPen *pen, GpLineCap *dashCap);
+#endif // DCR_USE_NEW_197819
+
+GpStatus WINGDIPAPI
+GdipSetPenLineJoin(GpPen *pen, GpLineJoin lineJoin);
+
+GpStatus WINGDIPAPI
+GdipGetPenLineJoin(GpPen *pen, GpLineJoin *lineJoin);
+
+GpStatus WINGDIPAPI
+GdipSetPenCustomStartCap(GpPen *pen, GpCustomLineCap* customCap);
+
+GpStatus WINGDIPAPI
+GdipGetPenCustomStartCap(GpPen *pen, GpCustomLineCap** customCap);
+
+GpStatus WINGDIPAPI
+GdipSetPenCustomEndCap(GpPen *pen, GpCustomLineCap* customCap);
+
+GpStatus WINGDIPAPI
+GdipGetPenCustomEndCap(GpPen *pen, GpCustomLineCap** customCap);
+
+GpStatus WINGDIPAPI
+GdipSetPenMiterLimit(GpPen *pen, REAL miterLimit);
+
+GpStatus WINGDIPAPI
+GdipGetPenMiterLimit(GpPen *pen, REAL *miterLimit);
+
+GpStatus WINGDIPAPI
+GdipSetPenMode(GpPen *pen, GpPenAlignment penMode);
+
+GpStatus WINGDIPAPI
+GdipGetPenMode(GpPen *pen, GpPenAlignment *penMode);
+
+GpStatus WINGDIPAPI
+GdipSetPenTransform(GpPen *pen, GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipGetPenTransform(GpPen *pen, GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipResetPenTransform(GpPen *pen);
+
+GpStatus WINGDIPAPI
+GdipMultiplyPenTransform(GpPen *pen, GDIPCONST GpMatrix *matrix,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipTranslatePenTransform(GpPen *pen, REAL dx, REAL dy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipScalePenTransform(GpPen *pen, REAL sx, REAL sy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipRotatePenTransform(GpPen *pen, REAL angle, GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipSetPenColor(GpPen *pen, ARGB argb);
+
+GpStatus WINGDIPAPI
+GdipGetPenColor(GpPen *pen, ARGB *argb);
+
+GpStatus WINGDIPAPI
+GdipSetPenBrushFill(GpPen *pen, GpBrush *brush);
+
+GpStatus WINGDIPAPI
+GdipGetPenBrushFill(GpPen *pen, GpBrush **brush);
+
+GpStatus WINGDIPAPI
+GdipGetPenFillType(GpPen *pen, GpPenType* type);
+
+GpStatus WINGDIPAPI
+GdipGetPenDashStyle(GpPen *pen, GpDashStyle *dashstyle);
+
+GpStatus WINGDIPAPI
+GdipSetPenDashStyle(GpPen *pen, GpDashStyle dashstyle);
+
+GpStatus WINGDIPAPI
+GdipGetPenDashOffset(GpPen *pen, REAL *offset);
+
+GpStatus WINGDIPAPI
+GdipSetPenDashOffset(GpPen *pen, REAL offset);
+
+GpStatus WINGDIPAPI
+GdipGetPenDashCount(GpPen *pen, INT *count);
+
+GpStatus WINGDIPAPI
+GdipSetPenDashArray(GpPen *pen, GDIPCONST REAL *dash, INT count);
+
+GpStatus WINGDIPAPI
+GdipGetPenDashArray(GpPen *pen, REAL *dash, INT count);
+
+GpStatus WINGDIPAPI
+GdipGetPenCompoundCount(GpPen *pen, INT *count);
+
+GpStatus WINGDIPAPI
+GdipSetPenCompoundArray(GpPen *pen, GDIPCONST REAL *dash, INT count);
+
+GpStatus WINGDIPAPI
+GdipGetPenCompoundArray(GpPen *pen, REAL *dash, INT count);
+
+//----------------------------------------------------------------------------
+// CustomLineCap methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateCustomLineCap(GpPath* fillPath, GpPath* strokePath,
+ GpLineCap baseCap, REAL baseInset, GpCustomLineCap **customCap);
+
+GpStatus WINGDIPAPI
+GdipDeleteCustomLineCap(GpCustomLineCap* customCap);
+
+GpStatus WINGDIPAPI
+GdipCloneCustomLineCap(GpCustomLineCap* customCap,
+ GpCustomLineCap** clonedCap);
+
+GpStatus WINGDIPAPI
+GdipGetCustomLineCapType(GpCustomLineCap* customCap,
+ CustomLineCapType* capType);
+
+GpStatus WINGDIPAPI
+GdipSetCustomLineCapStrokeCaps(GpCustomLineCap* customCap,
+ GpLineCap startCap, GpLineCap endCap);
+
+GpStatus WINGDIPAPI
+GdipGetCustomLineCapStrokeCaps(GpCustomLineCap* customCap,
+ GpLineCap* startCap, GpLineCap* endCap);
+
+GpStatus WINGDIPAPI
+GdipSetCustomLineCapStrokeJoin(GpCustomLineCap* customCap, GpLineJoin lineJoin);
+
+GpStatus WINGDIPAPI
+GdipGetCustomLineCapStrokeJoin(GpCustomLineCap* customCap, GpLineJoin* lineJoin);
+
+GpStatus WINGDIPAPI
+GdipSetCustomLineCapBaseCap(GpCustomLineCap* customCap, GpLineCap baseCap);
+
+GpStatus WINGDIPAPI
+GdipGetCustomLineCapBaseCap(GpCustomLineCap* customCap, GpLineCap* baseCap);
+
+GpStatus WINGDIPAPI
+GdipSetCustomLineCapBaseInset(GpCustomLineCap* customCap, REAL inset);
+
+GpStatus WINGDIPAPI
+GdipGetCustomLineCapBaseInset(GpCustomLineCap* customCap, REAL* inset);
+
+GpStatus WINGDIPAPI
+GdipSetCustomLineCapWidthScale(GpCustomLineCap* customCap, REAL widthScale);
+
+GpStatus WINGDIPAPI
+GdipGetCustomLineCapWidthScale(GpCustomLineCap* customCap, REAL* widthScale);
+
+//----------------------------------------------------------------------------
+// AdjustableArrowCap methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateAdjustableArrowCap(REAL height, REAL width, BOOL isFilled,
+ GpAdjustableArrowCap **cap);
+
+GpStatus WINGDIPAPI
+GdipSetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL height);
+
+GpStatus WINGDIPAPI
+GdipGetAdjustableArrowCapHeight(GpAdjustableArrowCap* cap, REAL* height);
+
+GpStatus WINGDIPAPI
+GdipSetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL width);
+
+GpStatus WINGDIPAPI
+GdipGetAdjustableArrowCapWidth(GpAdjustableArrowCap* cap, REAL* width);
+
+GpStatus WINGDIPAPI
+GdipSetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL middleInset);
+
+GpStatus WINGDIPAPI
+GdipGetAdjustableArrowCapMiddleInset(GpAdjustableArrowCap* cap, REAL* middleInset);
+
+GpStatus WINGDIPAPI
+GdipSetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL fillState);
+
+GpStatus WINGDIPAPI
+GdipGetAdjustableArrowCapFillState(GpAdjustableArrowCap* cap, BOOL* fillState);
+
+//----------------------------------------------------------------------------
+// Image methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipLoadImageFromStream(IStream* stream, GpImage **image);
+
+GpStatus WINGDIPAPI
+GdipLoadImageFromFile(GDIPCONST WCHAR* filename, GpImage **image);
+
+GpStatus WINGDIPAPI
+GdipLoadImageFromStreamICM(IStream* stream, GpImage **image);
+
+GpStatus WINGDIPAPI
+GdipLoadImageFromFileICM(GDIPCONST WCHAR* filename, GpImage **image);
+
+GpStatus WINGDIPAPI
+GdipCloneImage(GpImage *image, GpImage **cloneImage);
+
+GpStatus WINGDIPAPI
+GdipDisposeImage(GpImage *image);
+
+GpStatus WINGDIPAPI
+GdipSaveImageToFile(GpImage *image, GDIPCONST WCHAR* filename,
+ GDIPCONST CLSID* clsidEncoder, GDIPCONST EncoderParameters* encoderParams);
+
+GpStatus WINGDIPAPI
+GdipSaveImageToStream(GpImage *image, IStream* stream,
+ GDIPCONST CLSID* clsidEncoder, GDIPCONST EncoderParameters* encoderParams);
+
+GpStatus WINGDIPAPI
+GdipSaveAdd(GpImage *image, GDIPCONST EncoderParameters* encoderParams);
+
+GpStatus WINGDIPAPI
+GdipSaveAddImage(GpImage *image, GpImage* newImage,
+ GDIPCONST EncoderParameters* encoderParams);
+
+GpStatus WINGDIPAPI
+GdipGetImageGraphicsContext(GpImage *image, GpGraphics **graphics);
+
+GpStatus WINGDIPAPI
+GdipGetImageBounds(GpImage *image, GpRectF *srcRect, GpUnit *srcUnit);
+
+GpStatus WINGDIPAPI
+GdipGetImageDimension(GpImage *image, REAL *width, REAL *height);
+
+GpStatus WINGDIPAPI
+GdipGetImageType(GpImage *image, ImageType *type);
+
+GpStatus WINGDIPAPI
+GdipGetImageWidth(GpImage *image, UINT *width);
+
+GpStatus WINGDIPAPI
+GdipGetImageHeight(GpImage *image, UINT *height);
+
+GpStatus WINGDIPAPI
+GdipGetImageHorizontalResolution(GpImage *image, REAL *resolution);
+
+GpStatus WINGDIPAPI
+GdipGetImageVerticalResolution(GpImage *image, REAL *resolution);
+
+GpStatus WINGDIPAPI
+GdipGetImageFlags(GpImage *image, UINT *flags);
+
+GpStatus WINGDIPAPI
+GdipGetImageRawFormat(GpImage *image, GUID *format);
+
+GpStatus WINGDIPAPI
+GdipGetImagePixelFormat(GpImage *image, PixelFormat *format);
+
+GpStatus WINGDIPAPI
+GdipGetImageThumbnail(GpImage *image, UINT thumbWidth, UINT thumbHeight,
+ GpImage **thumbImage,
+ GetThumbnailImageAbort callback, VOID * callbackData);
+
+GpStatus WINGDIPAPI
+GdipGetEncoderParameterListSize(GpImage *image, GDIPCONST CLSID* clsidEncoder,
+ UINT* size);
+
+GpStatus WINGDIPAPI
+GdipGetEncoderParameterList(GpImage *image, GDIPCONST CLSID* clsidEncoder,
+ UINT size, EncoderParameters* buffer);
+
+GpStatus WINGDIPAPI
+GdipImageGetFrameDimensionsCount(GpImage* image, UINT* count);
+
+GpStatus WINGDIPAPI
+GdipImageGetFrameDimensionsList(GpImage* image, GUID* dimensionIDs, UINT count);
+
+GpStatus WINGDIPAPI
+GdipImageGetFrameCount(GpImage *image, GDIPCONST GUID* dimensionID, UINT* count);
+
+GpStatus WINGDIPAPI
+GdipImageSelectActiveFrame(GpImage *image, GDIPCONST GUID* dimensionID,
+ UINT frameIndex);
+
+GpStatus WINGDIPAPI
+GdipImageRotateFlip(GpImage *image, RotateFlipType rfType);
+
+GpStatus WINGDIPAPI
+GdipGetImagePalette(GpImage *image, ColorPalette *palette, INT size);
+
+GpStatus WINGDIPAPI
+GdipSetImagePalette(GpImage *image, GDIPCONST ColorPalette *palette);
+
+GpStatus WINGDIPAPI
+GdipGetImagePaletteSize(GpImage *image, INT *size);
+
+GpStatus WINGDIPAPI
+GdipGetPropertyCount(GpImage *image, UINT* numOfProperty);
+
+GpStatus WINGDIPAPI
+GdipGetPropertyIdList(GpImage *image, UINT numOfProperty, PROPID* list);
+
+GpStatus WINGDIPAPI
+GdipGetPropertyItemSize(GpImage *image, PROPID propId, UINT* size);
+
+GpStatus WINGDIPAPI
+GdipGetPropertyItem(GpImage *image, PROPID propId,UINT propSize,
+ PropertyItem* buffer);
+
+GpStatus WINGDIPAPI
+GdipGetPropertySize(GpImage *image, UINT* totalBufferSize, UINT* numProperties);
+
+GpStatus WINGDIPAPI
+GdipGetAllPropertyItems(GpImage *image, UINT totalBufferSize,
+ UINT numProperties, PropertyItem* allItems);
+
+GpStatus WINGDIPAPI
+GdipRemovePropertyItem(GpImage *image, PROPID propId);
+
+GpStatus WINGDIPAPI
+GdipSetPropertyItem(GpImage *image, GDIPCONST PropertyItem* item);
+
+GpStatus WINGDIPAPI
+GdipImageForceValidation(GpImage *image);
+
+GpStatus WINGDIPAPI
+GdipGetImageLayout(GpImage *image, ImageLayout* layout);
+
+GpStatus WINGDIPAPI
+GdipSetImageLayout(GpImage *image, GDIPCONST ImageLayout layout);
+
+//----------------------------------------------------------------------------
+// Bitmap methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromStream(IStream* stream, GpBitmap **bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromFile(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromStreamICM(IStream* stream, GpBitmap **bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromFileICM(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromScan0(INT width,
+ INT height,
+ INT stride,
+ PixelFormat format,
+ BYTE* scan0,
+ GpBitmap** bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromGraphics(INT width,
+ INT height,
+ GpGraphics* target,
+ GpBitmap** bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromDirectDrawSurface(IDirectDrawSurface7* surface,
+ GpBitmap** bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromGdiDib(GDIPCONST BITMAPINFO* gdiBitmapInfo,
+ VOID* gdiBitmapData,
+ GpBitmap** bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromHBITMAP(HBITMAP hbm,
+ HPALETTE hpal,
+ GpBitmap** bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateHBITMAPFromBitmap(GpBitmap* bitmap,
+ HBITMAP* hbmReturn,
+ ARGB background);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromHICON(HICON hicon,
+ GpBitmap** bitmap);
+
+GpStatus WINGDIPAPI
+GdipCreateHICONFromBitmap(GpBitmap* bitmap,
+ HICON* hbmReturn);
+
+GpStatus WINGDIPAPI
+GdipCreateBitmapFromResource(HINSTANCE hInstance,
+ GDIPCONST WCHAR* lpBitmapName,
+ GpBitmap** bitmap);
+
+GpStatus WINGDIPAPI
+GdipCloneBitmapArea(REAL x, REAL y, REAL width, REAL height,
+ PixelFormat format,
+ GpBitmap *srcBitmap,
+ GpBitmap **dstBitmap);
+
+GpStatus WINGDIPAPI
+GdipCloneBitmapAreaI(INT x,
+ INT y,
+ INT width,
+ INT height,
+ PixelFormat format,
+ GpBitmap *srcBitmap,
+ GpBitmap **dstBitmap);
+
+GpStatus WINGDIPAPI
+GdipBitmapLockBits(GpBitmap* bitmap,
+ GDIPCONST GpRect* rect,
+ UINT flags,
+ PixelFormat format,
+ BitmapData* lockedBitmapData);
+
+GpStatus WINGDIPAPI
+GdipBitmapUnlockBits(GpBitmap* bitmap,
+ BitmapData* lockedBitmapData);
+
+GpStatus WINGDIPAPI
+GdipBitmapGetPixel(GpBitmap* bitmap, INT x, INT y, ARGB *color);
+
+GpStatus WINGDIPAPI
+GdipBitmapSetPixel(GpBitmap* bitmap, INT x, INT y, ARGB color);
+
+GpStatus WINGDIPAPI
+GdipBitmapSetResolution(GpBitmap* bitmap, REAL xdpi, REAL ydpi);
+
+//----------------------------------------------------------------------------
+// ImageAttributes methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateImageAttributes(GpImageAttributes **imageattr);
+
+GpStatus WINGDIPAPI
+GdipCloneImageAttributes(GDIPCONST GpImageAttributes *imageattr,
+ GpImageAttributes **cloneImageattr);
+
+GpStatus WINGDIPAPI
+GdipDisposeImageAttributes(GpImageAttributes *imageattr);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesToIdentity(GpImageAttributes *imageattr,
+ ColorAdjustType type);
+GpStatus WINGDIPAPI
+GdipResetImageAttributes(GpImageAttributes *imageattr,
+ ColorAdjustType type);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesColorMatrix(GpImageAttributes *imageattr,
+ ColorAdjustType type,
+ BOOL enableFlag,
+ GDIPCONST ColorMatrix* colorMatrix,
+ GDIPCONST ColorMatrix* grayMatrix,
+ ColorMatrixFlags flags);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesThreshold(GpImageAttributes *imageattr,
+ ColorAdjustType type,
+ BOOL enableFlag,
+ REAL threshold);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesGamma(GpImageAttributes *imageattr,
+ ColorAdjustType type,
+ BOOL enableFlag,
+ REAL gamma);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesNoOp(GpImageAttributes *imageattr,
+ ColorAdjustType type,
+ BOOL enableFlag);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesColorKeys(GpImageAttributes *imageattr,
+ ColorAdjustType type,
+ BOOL enableFlag,
+ ARGB colorLow,
+ ARGB colorHigh);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesOutputChannel(GpImageAttributes *imageattr,
+ ColorAdjustType type,
+ BOOL enableFlag,
+ ColorChannelFlags channelFlags);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesOutputChannelColorProfile(GpImageAttributes *imageattr,
+ ColorAdjustType type,
+ BOOL enableFlag,
+ GDIPCONST WCHAR *colorProfileFilename);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesRemapTable(GpImageAttributes *imageattr,
+ ColorAdjustType type,
+ BOOL enableFlag,
+ UINT mapSize,
+ GDIPCONST ColorMap *map);
+GpStatus WINGDIPAPI
+GdipSetImageAttributesWrapMode(
+ GpImageAttributes *imageAttr,
+ WrapMode wrap,
+ ARGB argb,
+ BOOL clamp
+);
+
+GpStatus WINGDIPAPI
+GdipSetImageAttributesICMMode(
+ GpImageAttributes *imageAttr,
+ BOOL on
+);
+
+GpStatus WINGDIPAPI
+GdipGetImageAttributesAdjustedPalette(
+ GpImageAttributes *imageAttr,
+ ColorPalette * colorPalette,
+ ColorAdjustType colorAdjustType
+);
+
+//----------------------------------------------------------------------------
+// Graphics methods
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipFlush(GpGraphics *graphics, GpFlushIntention intention);
+
+GpStatus WINGDIPAPI
+GdipCreateFromHDC(HDC hdc, GpGraphics **graphics);
+
+GpStatus WINGDIPAPI
+GdipCreateFromHDC2(HDC hdc, HANDLE hDevice, GpGraphics **graphics);
+
+GpStatus WINGDIPAPI
+GdipCreateFromHWND(HWND hwnd, GpGraphics **graphics);
+
+GpStatus WINGDIPAPI
+GdipCreateFromHWNDICM(HWND hwnd, GpGraphics **graphics);
+
+GpStatus WINGDIPAPI
+GdipDeleteGraphics(GpGraphics *graphics);
+
+GpStatus WINGDIPAPI
+GdipGetDC(GpGraphics* graphics, HDC * hdc);
+
+GpStatus WINGDIPAPI
+GdipReleaseDC(GpGraphics* graphics, HDC hdc);
+
+GpStatus WINGDIPAPI
+GdipSetCompositingMode(GpGraphics *graphics, CompositingMode compositingMode);
+
+GpStatus WINGDIPAPI
+GdipGetCompositingMode(GpGraphics *graphics, CompositingMode *compositingMode);
+
+GpStatus WINGDIPAPI
+GdipSetRenderingOrigin(GpGraphics *graphics, INT x, INT y);
+
+GpStatus WINGDIPAPI
+GdipGetRenderingOrigin(GpGraphics *graphics, INT *x, INT *y);
+
+GpStatus WINGDIPAPI
+GdipSetCompositingQuality(GpGraphics *graphics, CompositingQuality compositingQuality);
+
+GpStatus WINGDIPAPI
+GdipGetCompositingQuality(GpGraphics *graphics, CompositingQuality *compositingQuality);
+
+GpStatus WINGDIPAPI
+GdipSetSmoothingMode(GpGraphics *graphics, SmoothingMode smoothingMode);
+
+GpStatus WINGDIPAPI
+GdipGetSmoothingMode(GpGraphics *graphics, SmoothingMode *smoothingMode);
+
+GpStatus WINGDIPAPI
+GdipSetPixelOffsetMode(GpGraphics* graphics, PixelOffsetMode pixelOffsetMode);
+
+GpStatus WINGDIPAPI
+GdipGetPixelOffsetMode(GpGraphics *graphics, PixelOffsetMode *pixelOffsetMode);
+
+GpStatus WINGDIPAPI
+GdipSetTextRenderingHint(GpGraphics *graphics, TextRenderingHint mode);
+
+GpStatus WINGDIPAPI
+GdipGetTextRenderingHint(GpGraphics *graphics, TextRenderingHint *mode);
+
+#ifdef DCR_USE_NEW_188922
+GpStatus WINGDIPAPI
+GdipSetTextContrast(GpGraphics *graphics, UINT contrast);
+
+GpStatus WINGDIPAPI
+GdipGetTextContrast(GpGraphics *graphics, UINT * contrast);
+#else
+GpStatus WINGDIPAPI
+GdipSetTextGammaValue(GpGraphics *graphics, UINT gammaValue);
+
+GpStatus WINGDIPAPI
+GdipGetTextGammaValue(GpGraphics *graphics, UINT * gammaValue);
+#endif // DCR_USE_NEW_188922
+
+
+GpStatus WINGDIPAPI
+GdipSetInterpolationMode(GpGraphics *graphics, InterpolationMode interpolationMode);
+
+GpStatus WINGDIPAPI
+GdipGetInterpolationMode(GpGraphics *graphics, InterpolationMode *interpolationMode);
+
+GpStatus WINGDIPAPI
+GdipSetWorldTransform(GpGraphics *graphics, GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipResetWorldTransform(GpGraphics *graphics);
+
+GpStatus WINGDIPAPI
+GdipMultiplyWorldTransform(GpGraphics *graphics, GDIPCONST GpMatrix *matrix,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipTranslateWorldTransform(GpGraphics *graphics, REAL dx, REAL dy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipScaleWorldTransform(GpGraphics *graphics, REAL sx, REAL sy,
+ GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipRotateWorldTransform(GpGraphics *graphics, REAL angle, GpMatrixOrder order);
+
+GpStatus WINGDIPAPI
+GdipGetWorldTransform(GpGraphics *graphics, GpMatrix *matrix);
+
+GpStatus WINGDIPAPI
+GdipResetPageTransform(GpGraphics *graphics);
+
+GpStatus WINGDIPAPI
+GdipGetPageUnit(GpGraphics *graphics, GpUnit *unit);
+
+GpStatus WINGDIPAPI
+GdipGetPageScale(GpGraphics *graphics, REAL *scale);
+
+GpStatus WINGDIPAPI
+GdipSetPageUnit(GpGraphics *graphics, GpUnit unit);
+
+GpStatus WINGDIPAPI
+GdipSetPageScale(GpGraphics *graphics, REAL scale);
+
+GpStatus WINGDIPAPI
+GdipGetDpiX(GpGraphics *graphics, REAL* dpi);
+
+GpStatus WINGDIPAPI
+GdipGetDpiY(GpGraphics *graphics, REAL* dpi);
+
+GpStatus WINGDIPAPI
+GdipTransformPoints(GpGraphics *graphics, GpCoordinateSpace destSpace,
+ GpCoordinateSpace srcSpace, GpPointF *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipTransformPointsI(GpGraphics *graphics, GpCoordinateSpace destSpace,
+ GpCoordinateSpace srcSpace, GpPoint *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipGetNearestColor(GpGraphics *graphics, ARGB* argb);
+
+// Create the Win9x Halftone Palette (even on NT) with correct Desktop colors
+HPALETTE WINGDIPAPI
+GdipCreateHalftonePalette();
+
+GpStatus WINGDIPAPI
+GdipDrawLine(GpGraphics *graphics, GpPen *pen, REAL x1, REAL y1,
+ REAL x2, REAL y2);
+
+GpStatus WINGDIPAPI
+GdipDrawLineI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1,
+ INT x2, INT y2);
+
+GpStatus WINGDIPAPI
+GdipDrawLines(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawLinesI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawArc(GpGraphics *graphics, GpPen *pen, REAL x, REAL y,
+ REAL width, REAL height, REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipDrawArcI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
+ INT width, INT height, REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipDrawBezier(GpGraphics *graphics, GpPen *pen, REAL x1, REAL y1,
+ REAL x2, REAL y2, REAL x3, REAL y3, REAL x4, REAL y4);
+
+GpStatus WINGDIPAPI
+GdipDrawBezierI(GpGraphics *graphics, GpPen *pen, INT x1, INT y1,
+ INT x2, INT y2, INT x3, INT y3, INT x4, INT y4);
+
+GpStatus WINGDIPAPI
+GdipDrawBeziers(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawBeziersI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawRectangle(GpGraphics *graphics, GpPen *pen, REAL x, REAL y,
+ REAL width, REAL height);
+
+GpStatus WINGDIPAPI
+GdipDrawRectangleI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
+ INT width, INT height);
+
+GpStatus WINGDIPAPI
+GdipDrawRectangles(GpGraphics *graphics, GpPen *pen, GDIPCONST GpRectF *rects,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawRectanglesI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpRect *rects,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawEllipse(GpGraphics *graphics, GpPen *pen, REAL x, REAL y,
+ REAL width, REAL height);
+
+GpStatus WINGDIPAPI
+GdipDrawEllipseI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
+ INT width, INT height);
+
+GpStatus WINGDIPAPI
+GdipDrawPie(GpGraphics *graphics, GpPen *pen, REAL x, REAL y,
+ REAL width, REAL height, REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipDrawPieI(GpGraphics *graphics, GpPen *pen, INT x, INT y,
+ INT width, INT height, REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipDrawPolygon(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawPolygonI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawPath(GpGraphics *graphics, GpPen *pen, GpPath *path);
+
+GpStatus WINGDIPAPI
+GdipDrawCurve(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawCurveI(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
+ INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawCurve2(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
+ INT count, REAL tension);
+
+GpStatus WINGDIPAPI
+GdipDrawCurve2I(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
+ INT count, REAL tension);
+
+GpStatus WINGDIPAPI
+GdipDrawCurve3(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPointF *points,
+ INT count, INT offset, INT numberOfSegments, REAL tension);
+
+GpStatus WINGDIPAPI
+GdipDrawCurve3I(GpGraphics *graphics, GpPen *pen, GDIPCONST GpPoint *points,
+ INT count, INT offset, INT numberOfSegments, REAL tension);
+
+GpStatus WINGDIPAPI
+GdipDrawClosedCurve(GpGraphics *graphics, GpPen *pen,
+ GDIPCONST GpPointF *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawClosedCurveI(GpGraphics *graphics, GpPen *pen,
+ GDIPCONST GpPoint *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawClosedCurve2(GpGraphics *graphics, GpPen *pen,
+ GDIPCONST GpPointF *points, INT count, REAL tension);
+
+GpStatus WINGDIPAPI
+GdipDrawClosedCurve2I(GpGraphics *graphics, GpPen *pen,
+ GDIPCONST GpPoint *points, INT count, REAL tension);
+
+GpStatus WINGDIPAPI
+GdipGraphicsClear(GpGraphics *graphics, ARGB color);
+
+GpStatus WINGDIPAPI
+GdipFillRectangle(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y,
+ REAL width, REAL height);
+
+GpStatus WINGDIPAPI
+GdipFillRectangleI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
+ INT width, INT height);
+
+GpStatus WINGDIPAPI
+GdipFillRectangles(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpRectF *rects, INT count);
+
+GpStatus WINGDIPAPI
+GdipFillRectanglesI(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpRect *rects, INT count);
+
+GpStatus WINGDIPAPI
+GdipFillPolygon(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPointF *points, INT count, GpFillMode fillMode);
+
+GpStatus WINGDIPAPI
+GdipFillPolygonI(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPoint *points, INT count, GpFillMode fillMode);
+
+GpStatus WINGDIPAPI
+GdipFillPolygon2(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPointF *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipFillPolygon2I(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPoint *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipFillEllipse(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y,
+ REAL width, REAL height);
+
+GpStatus WINGDIPAPI
+GdipFillEllipseI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
+ INT width, INT height);
+
+GpStatus WINGDIPAPI
+GdipFillPie(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y,
+ REAL width, REAL height, REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipFillPieI(GpGraphics *graphics, GpBrush *brush, INT x, INT y,
+ INT width, INT height, REAL startAngle, REAL sweepAngle);
+
+GpStatus WINGDIPAPI
+GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *path);
+
+GpStatus WINGDIPAPI
+GdipFillClosedCurve(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPointF *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipFillClosedCurveI(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPoint *points, INT count);
+
+GpStatus WINGDIPAPI
+GdipFillClosedCurve2(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPointF *points, INT count,
+ REAL tension, GpFillMode fillMode);
+
+GpStatus WINGDIPAPI
+GdipFillClosedCurve2I(GpGraphics *graphics, GpBrush *brush,
+ GDIPCONST GpPoint *points, INT count,
+ REAL tension, GpFillMode fillMode);
+
+GpStatus WINGDIPAPI
+GdipFillRegion(GpGraphics *graphics, GpBrush *brush,
+ GpRegion *region);
+
+GpStatus WINGDIPAPI
+GdipDrawImage(GpGraphics *graphics, GpImage *image, REAL x, REAL y);
+
+GpStatus WINGDIPAPI
+GdipDrawImageI(GpGraphics *graphics, GpImage *image, INT x, INT y);
+
+GpStatus WINGDIPAPI
+GdipDrawImageRect(GpGraphics *graphics, GpImage *image, REAL x, REAL y,
+ REAL width, REAL height);
+
+GpStatus WINGDIPAPI
+GdipDrawImageRectI(GpGraphics *graphics, GpImage *image, INT x, INT y,
+ INT width, INT height);
+
+GpStatus WINGDIPAPI
+GdipDrawImagePoints(GpGraphics *graphics, GpImage *image,
+ GDIPCONST GpPointF *dstpoints, INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawImagePointsI(GpGraphics *graphics, GpImage *image,
+ GDIPCONST GpPoint *dstpoints, INT count);
+
+GpStatus WINGDIPAPI
+GdipDrawImagePointRect(GpGraphics *graphics, GpImage *image, REAL x,
+ REAL y, REAL srcx, REAL srcy, REAL srcwidth,
+ REAL srcheight, GpUnit srcUnit);
+
+GpStatus WINGDIPAPI
+GdipDrawImagePointRectI(GpGraphics *graphics, GpImage *image, INT x,
+ INT y, INT srcx, INT srcy, INT srcwidth,
+ INT srcheight, GpUnit srcUnit);
+
+GpStatus WINGDIPAPI
+GdipDrawImageRectRect(GpGraphics *graphics, GpImage *image, REAL dstx,
+ REAL dsty, REAL dstwidth, REAL dstheight,
+ REAL srcx, REAL srcy, REAL srcwidth, REAL srcheight,
+ GpUnit srcUnit,
+ GDIPCONST GpImageAttributes* imageAttributes,
+ DrawImageAbort callback, VOID * callbackData);
+
+GpStatus WINGDIPAPI
+GdipDrawImageRectRectI(GpGraphics *graphics, GpImage *image, INT dstx,
+ INT dsty, INT dstwidth, INT dstheight,
+ INT srcx, INT srcy, INT srcwidth, INT srcheight,
+ GpUnit srcUnit,
+ GDIPCONST GpImageAttributes* imageAttributes,
+ DrawImageAbort callback, VOID * callbackData);
+
+GpStatus WINGDIPAPI
+GdipDrawImagePointsRect(GpGraphics *graphics, GpImage *image,
+ GDIPCONST GpPointF *points, INT count, REAL srcx,
+ REAL srcy, REAL srcwidth, REAL srcheight,
+ GpUnit srcUnit,
+ GDIPCONST GpImageAttributes* imageAttributes,
+ DrawImageAbort callback, VOID * callbackData);
+
+GpStatus WINGDIPAPI
+GdipDrawImagePointsRectI(GpGraphics *graphics, GpImage *image,
+ GDIPCONST GpPoint *points, INT count, INT srcx,
+ INT srcy, INT srcwidth, INT srcheight,
+ GpUnit srcUnit,
+ GDIPCONST GpImageAttributes* imageAttributes,
+ DrawImageAbort callback, VOID * callbackData);
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileDestPoint(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST PointF & destPoint,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileDestPointI(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST Point & destPoint,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileDestRect(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST RectF & destRect,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileDestRectI(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST Rect & destRect,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileDestPoints(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST PointF * destPoints,
+ INT count,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileDestPointsI(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST Point * destPoints,
+ INT count,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileSrcRectDestPoint(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST PointF & destPoint,
+ GDIPCONST RectF & srcRect,
+ Unit srcUnit,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileSrcRectDestPointI(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST Point & destPoint,
+ GDIPCONST Rect & srcRect,
+ Unit srcUnit,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileSrcRectDestRect(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST RectF & destRect,
+ GDIPCONST RectF & srcRect,
+ Unit srcUnit,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileSrcRectDestRectI(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST Rect & destRect,
+ GDIPCONST Rect & srcRect,
+ Unit srcUnit,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileSrcRectDestPoints(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST PointF * destPoints,
+ INT count,
+ GDIPCONST RectF & srcRect,
+ Unit srcUnit,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipEnumerateMetafileSrcRectDestPointsI(
+ GpGraphics * graphics,
+ GDIPCONST GpMetafile * metafile,
+ GDIPCONST Point * destPoints,
+ INT count,
+ GDIPCONST Rect & srcRect,
+ Unit srcUnit,
+ EnumerateMetafileProc callback,
+ VOID * callbackData,
+ GDIPCONST GpImageAttributes * imageAttributes
+ );
+
+GpStatus WINGDIPAPI
+GdipPlayMetafileRecord(
+ GDIPCONST GpMetafile * metafile,
+ EmfPlusRecordType recordType,
+ UINT flags,
+ UINT dataSize,
+ GDIPCONST BYTE * data
+ );
+
+GpStatus WINGDIPAPI
+GdipSetClipGraphics(GpGraphics *graphics, GpGraphics *srcgraphics,
+ CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipSetClipRect(GpGraphics *graphics, REAL x, REAL y,
+ REAL width, REAL height, CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipSetClipRectI(GpGraphics *graphics, INT x, INT y,
+ INT width, INT height, CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipSetClipPath(GpGraphics *graphics, GpPath *path, CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipSetClipRegion(GpGraphics *graphics, GpRegion *region,
+ CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipSetClipHrgn(GpGraphics *graphics, HRGN hRgn, CombineMode combineMode);
+
+GpStatus WINGDIPAPI
+GdipResetClip(GpGraphics *graphics);
+
+GpStatus WINGDIPAPI
+GdipTranslateClip(GpGraphics *graphics, REAL dx, REAL dy);
+
+GpStatus WINGDIPAPI
+GdipTranslateClipI(GpGraphics *graphics, INT dx, INT dy);
+
+GpStatus WINGDIPAPI
+GdipGetClip(GpGraphics *graphics, GpRegion *region);
+
+GpStatus WINGDIPAPI
+GdipGetClipBounds(GpGraphics *graphics, GpRectF *rect);
+
+GpStatus WINGDIPAPI
+GdipGetClipBoundsI(GpGraphics *graphics, GpRect *rect);
+
+GpStatus WINGDIPAPI
+GdipIsClipEmpty(GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipGetVisibleClipBounds(GpGraphics *graphics, GpRectF *rect);
+
+GpStatus WINGDIPAPI
+GdipGetVisibleClipBoundsI(GpGraphics *graphics, GpRect *rect);
+
+GpStatus WINGDIPAPI
+GdipIsVisibleClipEmpty(GpGraphics *graphics, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsVisiblePoint(GpGraphics *graphics, REAL x, REAL y,
+ BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsVisiblePointI(GpGraphics *graphics, INT x, INT y,
+ BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsVisibleRect(GpGraphics *graphics, REAL x, REAL y,
+ REAL width, REAL height, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipIsVisibleRectI(GpGraphics *graphics, INT x, INT y,
+ INT width, INT height, BOOL *result);
+
+GpStatus WINGDIPAPI
+GdipSaveGraphics(GpGraphics *graphics, GraphicsState *state);
+
+GpStatus WINGDIPAPI
+GdipRestoreGraphics(GpGraphics *graphics, GraphicsState state);
+
+GpStatus WINGDIPAPI
+GdipBeginContainer(GpGraphics *graphics, GDIPCONST GpRectF* dstrect,
+ GDIPCONST GpRectF *srcrect, GpUnit unit, GraphicsContainer *state);
+
+GpStatus WINGDIPAPI
+GdipBeginContainerI(GpGraphics *graphics, GDIPCONST GpRect* dstrect,
+ GDIPCONST GpRect *srcrect, GpUnit unit, GraphicsContainer *state);
+
+GpStatus WINGDIPAPI
+GdipBeginContainer2(GpGraphics *graphics, GraphicsContainer* state);
+
+GpStatus WINGDIPAPI
+GdipEndContainer(GpGraphics *graphics, GraphicsContainer state);
+
+GpStatus
+GdipGetMetafileHeaderFromWmf(
+ HMETAFILE hWmf,
+ GDIPCONST APMFileHeader * apmFileHeader,
+ MetafileHeader * header
+ );
+
+GpStatus
+WINGDIPAPI
+GdipGetMetafileHeaderFromEmf(
+ HENHMETAFILE hEmf,
+ MetafileHeader * header
+ );
+
+GpStatus
+WINGDIPAPI
+GdipGetMetafileHeaderFromFile(
+ GDIPCONST WCHAR* filename,
+ MetafileHeader * header
+ );
+
+GpStatus
+WINGDIPAPI
+GdipGetMetafileHeaderFromStream(
+ IStream * stream,
+ MetafileHeader * header
+ );
+
+GpStatus
+WINGDIPAPI
+GdipGetMetafileHeaderFromMetafile(
+ GpMetafile * metafile,
+ MetafileHeader * header
+ );
+
+GpStatus
+WINGDIPAPI
+GdipGetHemfFromMetafile(
+ GpMetafile * metafile,
+ HENHMETAFILE * hEmf
+ );
+
+GpStatus WINGDIPAPI
+GdipCreateStreamOnFile(GDIPCONST WCHAR * filename, UINT access, IStream **stream);
+
+GpStatus WINGDIPAPI
+GdipCreateMetafileFromWmf(HMETAFILE hWmf, BOOL deleteWmf,
+ GDIPCONST APMFileHeader * apmFileHeader, GpMetafile **metafile);
+
+GpStatus WINGDIPAPI
+GdipCreateMetafileFromEmf(HENHMETAFILE hEmf, BOOL deleteEmf,
+ GpMetafile **metafile);
+
+GpStatus WINGDIPAPI
+GdipCreateMetafileFromFile(GDIPCONST WCHAR* file, GpMetafile **metafile);
+
+GpStatus WINGDIPAPI
+GdipCreateMetafileFromWmfFile(GDIPCONST WCHAR* file, GDIPCONST APMFileHeader * apmFileHeader, GpMetafile **metafile);
+
+GpStatus WINGDIPAPI
+GdipCreateMetafileFromStream(IStream * stream, GpMetafile **metafile);
+
+GpStatus WINGDIPAPI
+GdipRecordMetafile(
+ HDC referenceHdc,
+ EmfType type,
+ GDIPCONST GpRectF * frameRect,
+ MetafileFrameUnit frameUnit,
+ GDIPCONST WCHAR * description,
+ GpMetafile ** metafile
+ );
+
+GpStatus WINGDIPAPI
+GdipRecordMetafileI(
+ HDC referenceHdc,
+ EmfType type,
+ GDIPCONST GpRect * frameRect,
+ MetafileFrameUnit frameUnit,
+ GDIPCONST WCHAR * description,
+ GpMetafile ** metafile
+ );
+
+GpStatus WINGDIPAPI
+GdipRecordMetafileFileName(
+ GDIPCONST WCHAR* fileName,
+ HDC referenceHdc,
+ EmfType type,
+ GDIPCONST GpRectF * frameRect,
+ MetafileFrameUnit frameUnit,
+ GDIPCONST WCHAR * description,
+ GpMetafile ** metafile
+ );
+
+GpStatus WINGDIPAPI
+GdipRecordMetafileFileNameI(
+ GDIPCONST WCHAR* fileName,
+ HDC referenceHdc,
+ EmfType type,
+ GDIPCONST GpRect * frameRect,
+ MetafileFrameUnit frameUnit,
+ GDIPCONST WCHAR * description,
+ GpMetafile ** metafile
+ );
+
+GpStatus WINGDIPAPI
+GdipRecordMetafileStream(
+ IStream * stream,
+ HDC referenceHdc,
+ EmfType type,
+ GDIPCONST GpRectF * frameRect,
+ MetafileFrameUnit frameUnit,
+ GDIPCONST WCHAR * description,
+ GpMetafile ** metafile
+ );
+
+GpStatus WINGDIPAPI
+GdipRecordMetafileStreamI(
+ IStream * stream,
+ HDC referenceHdc,
+ EmfType type,
+ GDIPCONST GpRect * frameRect,
+ MetafileFrameUnit frameUnit,
+ GDIPCONST WCHAR * description,
+ GpMetafile ** metafile
+ );
+
+GpStatus WINGDIPAPI
+GdipSetMetafileDownLevelRasterizationLimit(
+ GpMetafile * metafile,
+ UINT metafileRasterizationLimitDpi
+ );
+
+GpStatus WINGDIPAPI
+GdipGetMetafileDownLevelRasterizationLimit(
+ GDIPCONST GpMetafile * metafile,
+ UINT * metafileRasterizationLimitDpi
+ );
+
+GpStatus WINGDIPAPI
+GdipGetImageDecodersSize(UINT *numDecoders, UINT *size);
+
+GpStatus WINGDIPAPI
+GdipGetImageDecoders(UINT numDecoders,
+ UINT size,
+ ImageCodecInfo *decoders);
+
+GpStatus WINGDIPAPI
+GdipGetImageEncodersSize(UINT *numEncoders, UINT *size);
+
+GpStatus WINGDIPAPI
+GdipGetImageEncoders(UINT numEncoders,
+ UINT size,
+ ImageCodecInfo *encoders);
+
+GpStatus WINGDIPAPI
+GdipAddImageCodec(GDIPCONST ImageCodecInfo *codec);
+
+GpStatus WINGDIPAPI
+GdipRemoveImageCodec(GDIPCONST ImageCodecInfo *codec);
+
+#ifndef DCR_USE_NEW_186091
+GpStatus WINGDIPAPI
+GdipGetGraphicsPixel(GpGraphics* graphics, REAL x, REAL y, ARGB* argb);
+#endif
+
+GpStatus WINGDIPAPI
+GdipComment(GpGraphics* graphics, UINT sizeData, GDIPCONST BYTE * data);
+
+GpStatus WINGDIPAPI
+GdipGetGraphicsLayout(GpGraphics* graphics, GraphicsLayout* layout);
+
+GpStatus WINGDIPAPI
+GdipSetGraphicsLayout(GpGraphics* graphics, GDIPCONST GraphicsLayout layout);
+
+//----------------------------------------------------------------------------
+// FontFamily
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateFontFamilyFromName(GDIPCONST WCHAR *name,
+ GpFontCollection *fontCollection,
+ GpFontFamily **FontFamily);
+
+GpStatus WINGDIPAPI
+GdipDeleteFontFamily(GpFontFamily *FontFamily);
+
+GpStatus WINGDIPAPI
+GdipCloneFontFamily(GpFontFamily *FontFamily, GpFontFamily **clonedFontFamily);
+
+GpStatus WINGDIPAPI
+GdipGetGenericFontFamilySansSerif(GpFontFamily **nativeFamily);
+
+GpStatus WINGDIPAPI
+GdipGetGenericFontFamilySerif(GpFontFamily **nativeFamily);
+
+GpStatus WINGDIPAPI
+GdipGetGenericFontFamilyMonospace(GpFontFamily **nativeFamily);
+
+
+GpStatus WINGDIPAPI
+GdipGetFamilyName(
+ GDIPCONST GpFontFamily *family,
+ WCHAR name[LF_FACESIZE],
+ LANGID language
+);
+
+GpStatus WINGDIPAPI
+GdipIsStyleAvailable(GDIPCONST GpFontFamily *family, INT style, BOOL * IsStyleAvailable);
+
+GpStatus WINGDIPAPI
+GdipFontCollectionEnumerable(
+ GpFontCollection* fontCollection,
+ GpGraphics* graphics,
+ INT * numFound
+);
+
+GpStatus WINGDIPAPI GdipFontCollectionEnumerate(
+ GpFontCollection* fontCollection,
+ INT numSought,
+ GpFontFamily* gpfamilies[],
+ INT* numFound,
+ GpGraphics* graphics
+);
+
+//-----------------------------------
+// New API
+//-----------------------------------
+
+GpStatus WINGDIPAPI
+GdipGetEmHeight(GDIPCONST GpFontFamily *family, INT style, UINT16 * EmHeight);
+
+GpStatus WINGDIPAPI
+GdipGetCellAscent(GDIPCONST GpFontFamily *family, INT style, UINT16 * CellAscent);
+
+GpStatus WINGDIPAPI
+GdipGetCellDescent(GDIPCONST GpFontFamily *family, INT style, UINT16 * CellDescent);
+
+GpStatus WINGDIPAPI
+GdipGetLineSpacing(GDIPCONST GpFontFamily *family, INT style, UINT16 * LineSpacing);
+
+
+//----------------------------------------------------------------------------
+// Font
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateFontFromDC(
+ HDC hdc,
+ GpFont **font
+);
+
+GpStatus WINGDIPAPI
+GdipCreateFontFromLogfontA(
+ HDC hdc,
+ GDIPCONST LOGFONTA *logfont,
+ GpFont **font
+);
+
+GpStatus WINGDIPAPI
+GdipCreateFontFromLogfontW(
+ HDC hdc,
+ GDIPCONST LOGFONTW *logfont,
+ GpFont **font
+);
+
+GpStatus WINGDIPAPI
+GdipCreateFont(
+ GDIPCONST GpFontFamily *fontFamily,
+ REAL emSize,
+ INT style,
+ Unit unit,
+ GpFont **font
+);
+
+GpStatus WINGDIPAPI
+GdipCloneFont(GpFont* font, GpFont** cloneFont);
+
+GpStatus WINGDIPAPI
+GdipDeleteFont(GpFont* font);
+
+GpStatus WINGDIPAPI
+GdipGetFamily(GpFont *font, GpFontFamily **family);
+
+GpStatus WINGDIPAPI
+GdipGetFontStyle(GpFont *font, INT *style);
+
+GpStatus WINGDIPAPI
+GdipGetFontSize(GpFont *font, REAL *size);
+
+GpStatus WINGDIPAPI
+GdipGetFontUnit(GpFont *font, Unit *unit);
+
+GpStatus WINGDIPAPI
+GdipGetFontHeight(GDIPCONST GpFont *font, GDIPCONST GpGraphics *graphics, REAL *height);
+
+#ifdef DCR_USE_NEW_125467
+GpStatus WINGDIPAPI
+GdipGetFontHeightGivenDPI(GDIPCONST GpFont *font, REAL dpi, REAL *height);
+#endif
+
+GpStatus WINGDIPAPI
+GdipGetLogFontA(GpFont * font, GpGraphics *graphics, LOGFONTA * logfontA);
+
+GpStatus WINGDIPAPI
+GdipGetLogFontW(GpFont * font, GpGraphics *graphics, LOGFONTW * logfontW);
+
+// FontCollection
+
+GpStatus WINGDIPAPI
+GdipNewInstalledFontCollection(GpFontCollection** fontCollection);
+
+GpStatus WINGDIPAPI
+GdipNewPrivateFontCollection(GpFontCollection** fontCollection);
+
+GpStatus WINGDIPAPI
+GdipDeletePrivateFontCollection(GpFontCollection** fontCollection);
+
+GpStatus WINGDIPAPI
+GdipGetFontCollectionFamilyCount(
+ GpFontCollection* fontCollection,
+ INT * numFound
+);
+
+GpStatus WINGDIPAPI
+GdipGetFontCollectionFamilyList(
+ GpFontCollection* fontCollection,
+ INT numSought,
+ GpFontFamily* gpfamilies[],
+ INT* numFound
+);
+
+#ifndef DCR_USE_NEW_235072
+GpStatus WINGDIPAPI
+GdipInstallFontFile(
+ GpFontCollection* fontCollection,
+ GDIPCONST WCHAR* filename
+);
+
+GpStatus WINGDIPAPI
+GdipUninstallFontFile(
+ GpFontCollection* fontCollection,
+ GDIPCONST WCHAR* filename
+);
+#endif
+
+GpStatus WINGDIPAPI
+GdipPrivateAddFontFile(
+ GpFontCollection* fontCollection,
+ GDIPCONST WCHAR* filename
+);
+
+GpStatus WINGDIPAPI
+GdipPrivateAddMemoryFont(
+ GpFontCollection* fontCollection,
+ GDIPCONST void* memory,
+ INT length
+);
+
+//----------------------------------------------------------------------------
+// Text
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipDrawString(
+ GpGraphics *graphics,
+ GDIPCONST WCHAR *string,
+ INT length,
+ GDIPCONST GpFont *font,
+ GDIPCONST RectF *layoutRect,
+ GDIPCONST GpStringFormat *stringFormat,
+ GDIPCONST GpBrush *brush
+);
+
+GpStatus WINGDIPAPI
+GdipMeasureString(
+ GpGraphics *graphics,
+ GDIPCONST WCHAR *string,
+ INT length,
+ GDIPCONST GpFont *font,
+ GDIPCONST RectF *layoutRect,
+ GDIPCONST GpStringFormat *stringFormat,
+ RectF *boundingBox,
+ INT *codepointsFitted,
+ INT *linesFilled
+);
+
+#ifndef DCR_USE_NEW_174340
+GpStatus WINGDIPAPI
+GdipMeasureStringRegion(
+ GpGraphics *graphics,
+ GDIPCONST WCHAR *string,
+ INT length,
+ GDIPCONST GpFont *font,
+ GDIPCONST RectF &layoutRect,
+ GDIPCONST GpStringFormat *stringFormat,
+ INT firstCharacterIndex,
+ INT characterCount,
+ GpRegion *region
+);
+#endif
+
+#ifdef DCR_USE_NEW_174340
+GpStatus
+WINGDIPAPI
+GdipMeasureCharacterRanges(
+ GpGraphics *graphics,
+ GDIPCONST WCHAR *string,
+ INT length,
+ GDIPCONST GpFont *font,
+ GDIPCONST RectF &layoutRect,
+ GDIPCONST GpStringFormat *stringFormat,
+ INT regionCount,
+ GpRegion **regions
+);
+#endif
+
+GpStatus WINGDIPAPI
+GdipDrawDriverString(
+ GpGraphics *graphics,
+ GDIPCONST UINT16 *text,
+ INT length,
+ GDIPCONST GpFont *font,
+ GDIPCONST GpBrush *brush,
+ GDIPCONST PointF *positions,
+ INT flags,
+ GDIPCONST GpMatrix *matrix
+);
+
+GpStatus WINGDIPAPI
+GdipMeasureDriverString(
+ GpGraphics *graphics,
+ GDIPCONST UINT16 *text,
+ INT length,
+ GDIPCONST GpFont *font,
+ GDIPCONST PointF *positions,
+ INT flags,
+ GDIPCONST GpMatrix *matrix,
+ RectF *boundingBox
+);
+
+#ifndef DCR_USE_NEW_168772
+GpStatus WINGDIPAPI
+GdipDriverStringPointToCodepoint(
+ GpGraphics *graphics,
+ GDIPCONST UINT16 *text,
+ INT length,
+ GDIPCONST GpFont *font,
+ GDIPCONST PointF *positions,
+ INT flags,
+ GpMatrix *matrix,
+ GDIPCONST PointF *hit,
+ INT *index,
+ BOOL *rightEdge,
+ REAL *distance
+);
+#endif
+
+//----------------------------------------------------------------------------
+// String format APIs
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateStringFormat(
+ INT formatAttributes,
+ LANGID language,
+ GpStringFormat **format
+);
+
+GpStatus WINGDIPAPI
+GdipStringFormatGetGenericDefault(GpStringFormat **format);
+
+GpStatus WINGDIPAPI
+GdipStringFormatGetGenericTypographic(GpStringFormat **format);
+
+GpStatus WINGDIPAPI
+GdipDeleteStringFormat(GpStringFormat *format);
+
+GpStatus WINGDIPAPI
+GdipCloneStringFormat(GDIPCONST GpStringFormat *format, GpStringFormat **newFormat);
+
+GpStatus WINGDIPAPI
+GdipSetStringFormatFlags(GpStringFormat *format, INT flags);
+
+GpStatus WINGDIPAPI GdipGetStringFormatFlags(GDIPCONST GpStringFormat *format, INT *flags);
+
+#ifndef DCR_USE_NEW_152154
+GpStatus WINGDIPAPI
+GdipSetStringFormatLineSpacing(GpStringFormat *format, REAL amount,
+ LineSpacing method);
+
+GpStatus WINGDIPAPI
+GdipGetStringFormatLineSpacingAmount(GDIPCONST GpStringFormat *format, REAL *amount);
+GpStatus WINGDIPAPI
+GdipGetStringFormatLineSpacingMethod(GDIPCONST GpStringFormat *format, LineSpacing *method);
+#endif
+
+GpStatus WINGDIPAPI
+GdipSetStringFormatAlign(GpStringFormat *format, StringAlignment align);
+
+GpStatus WINGDIPAPI
+GdipGetStringFormatAlign(GDIPCONST GpStringFormat *format, StringAlignment *align);
+
+GpStatus WINGDIPAPI
+GdipSetStringFormatLineAlign(GpStringFormat *format,
+ StringAlignment align);
+
+GpStatus WINGDIPAPI
+GdipGetStringFormatLineAlign(GDIPCONST GpStringFormat *format,
+ StringAlignment *align);
+
+GpStatus WINGDIPAPI
+GdipSetStringFormatTrimming(
+ GpStringFormat *format,
+ StringTrimming trimming
+);
+
+GpStatus WINGDIPAPI
+GdipGetStringFormatTrimming(
+ GDIPCONST GpStringFormat *format,
+ StringTrimming *trimming
+);
+
+GpStatus WINGDIPAPI
+GdipSetStringFormatHotkeyPrefix(GpStringFormat *format, INT hotkeyPrefix);
+
+GpStatus WINGDIPAPI
+GdipGetStringFormatHotkeyPrefix(GDIPCONST GpStringFormat *format, INT *hotkeyPrefix);
+
+GpStatus WINGDIPAPI
+GdipSetStringFormatTabStops(GpStringFormat *format, REAL firstTabOffset, INT count, GDIPCONST REAL *tabStops);
+
+GpStatus WINGDIPAPI
+GdipGetStringFormatTabStops(GDIPCONST GpStringFormat *format, INT count, REAL *firstTabOffset, REAL *tabStops);
+
+GpStatus WINGDIPAPI
+GdipGetStringFormatTabStopCount(GDIPCONST GpStringFormat *format, INT * count);
+
+#ifdef DCR_USE_NEW_146933
+GpStatus WINGDIPAPI
+GdipSetStringFormatDigitSubstitution(GpStringFormat *format, LANGID language,
+ StringDigitSubstitute substitute);
+
+GpStatus WINGDIPAPI
+GdipGetStringFormatDigitSubstitution(GDIPCONST GpStringFormat *format, LANGID *language,
+ StringDigitSubstitute *substitute);
+#endif // DCR_USE_NEW_146933
+
+#ifdef DCR_USE_NEW_174340
+GpStatus WINGDIPAPI
+GdipGetStringFormatMeasurableCharacterRangeCount(
+ GDIPCONST GpStringFormat *format,
+ INT *count
+);
+
+GpStatus WINGDIPAPI
+GdipSetStringFormatMeasurableCharacterRanges(
+ GpStringFormat *format,
+ INT rangeCount,
+ GDIPCONST CharacterRange *ranges
+);
+#endif
+
+//----------------------------------------------------------------------------
+// Cached Bitmap APIs
+//----------------------------------------------------------------------------
+
+GpStatus WINGDIPAPI
+GdipCreateCachedBitmap(
+ GpBitmap *bitmap,
+ GpGraphics *graphics,
+ GpCachedBitmap **cachedBitmap
+);
+
+GpStatus WINGDIPAPI
+GdipDeleteCachedBitmap(GpCachedBitmap *cachedBitmap);
+
+GpStatus WINGDIPAPI
+GdipDrawCachedBitmap(
+ GpGraphics *graphics,
+ GpCachedBitmap *cachedBitmap,
+ INT x,
+ INT y
+);
+
+UINT WINGDIPAPI
+GdipEmfToWmfBits(
+ HENHMETAFILE hemf,
+ UINT cbData16,
+ LPBYTE pData16,
+ INT iMapMode,
+ INT eFlags
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !_FLATAPI_H
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusFont.h b/core/src/fxge/Microsoft SDK/include/GdiPlusFont.h
index c9ff050561..4c9e01f589 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusFont.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusFont.h
@@ -1,299 +1,299 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusFont.h
-*
-* Abstract:
-*
-* Font related declarations
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSFONT_H
-#define _GDIPLUSFONT_H
-
-inline
-Font::Font(IN HDC hdc)
-{
- GpFont *font = NULL;
- lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) lastResult >= 10)
- lastResult = NotFound;
-#endif
-
- SetNativeFont(font);
-}
-
-#ifdef DCR_USE_NEW_127084
-inline
-Font::Font(IN HDC hdc,
- IN const HFONT hfont)
-{
- GpFont *font = NULL;
-
- if (hfont)
- {
- LOGFONTA lf;
-
- if(GetObjectA(hfont, sizeof(LOGFONTA), &lf))
- lastResult = DllExports::GdipCreateFontFromLogfontA(hdc, &lf, &font);
- else
- lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
- }
- else
- {
- lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
- }
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) lastResult >= 10)
- lastResult = NotFound;
-#endif
-
- SetNativeFont(font);
-}
-#endif
-
-inline
-Font::Font(IN HDC hdc,
- IN const LOGFONTW* logfont)
-{
- GpFont *font = NULL;
- if (logfont)
- {
- lastResult = DllExports::GdipCreateFontFromLogfontW(hdc, logfont, &font);
- }
- else
- {
- lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
- }
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) lastResult >= 10)
- lastResult = NotFound;
-#endif
-
- SetNativeFont(font);
-}
-
-inline
-Font::Font(IN HDC hdc,
- IN const LOGFONTA* logfont)
-{
- GpFont *font = NULL;
-
- if (logfont)
- {
- lastResult = DllExports::GdipCreateFontFromLogfontA(hdc, logfont, &font);
- }
- else
- {
- lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
- }
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) lastResult >= 10)
- lastResult = NotFound;
-#endif
-
- SetNativeFont(font);
-}
-
-inline
-Font::Font(
- IN const FontFamily * family,
- IN REAL emSize,
- IN INT style,
- IN Unit unit
-)
-{
- GpFont *font = NULL;
-
- lastResult = DllExports::GdipCreateFont(family ? family->nativeFamily : NULL,
- emSize,
- style,
- unit,
- &font);
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) lastResult >= 10)
- lastResult = NotFound;
-#endif
-
- SetNativeFont(font);
-}
-
-inline
-Font::Font(
- IN const WCHAR * familyName,
- IN REAL emSize,
- IN INT style,
- IN Unit unit,
- IN const FontCollection * fontCollection
-)
-{
- FontFamily family(familyName, fontCollection);
-
- GpFont * font = NULL;
-
- lastResult = family.GetLastStatus();
-
- if (lastResult == Ok)
- {
- lastResult = DllExports::GdipCreateFont(family.nativeFamily,
- emSize,
- style,
- unit,
- &font);
- }
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) lastResult >= 10)
- lastResult = NotFound;
-#endif
-
- SetNativeFont(font);
-}
-
-inline Status
-Font::GetLogFontA(IN const Graphics *g,
- OUT LOGFONTA *logfontA) const
-{
- return SetStatus(DllExports::GdipGetLogFontA(nativeFont, g ? g->nativeGraphics : NULL, logfontA));
-
-}
-
-inline Status
-Font::GetLogFontW(IN const Graphics *g,
- OUT LOGFONTW *logfontW) const
-{
- return SetStatus(DllExports::GdipGetLogFontW(nativeFont, g ? g->nativeGraphics : NULL, logfontW));
-}
-
-
-inline Font*
-Font::Clone() const
-{
- GpFont *cloneFont = NULL;
-
- SetStatus(DllExports::GdipCloneFont(nativeFont, &cloneFont));
-
- return new Font(cloneFont, lastResult);
-}
-
-inline
-Font::~Font()
-{
- DllExports::GdipDeleteFont(nativeFont);
-}
-
-// Operations
-
-inline BOOL
-Font::IsAvailable() const
-{
- return (nativeFont ? TRUE : FALSE);
-}
-
-inline Status
-Font::GetFamily(OUT FontFamily *family) const
-{
- if (family == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- Status status = DllExports::GdipGetFamily(nativeFont, &(family->nativeFamily));
- family->SetStatus(status);
-
- return SetStatus(status);
-}
-
-inline INT
-Font::GetStyle() const
-{
- INT style;
-
- SetStatus(DllExports::GdipGetFontStyle(nativeFont, &style));
-
- return style;
-}
-
-inline REAL
-Font::GetSize() const
-{
- REAL size;
- SetStatus(DllExports::GdipGetFontSize(nativeFont, &size));
- return size;
-}
-
-inline Unit
-Font::GetUnit() const
-{
- Unit unit;
- SetStatus(DllExports::GdipGetFontUnit(nativeFont, &unit));
- return unit;
-}
-
-inline REAL
-Font::GetHeight(IN const Graphics *graphics) const
-{
- REAL height;
- SetStatus(DllExports::GdipGetFontHeight(
- nativeFont,
- graphics ? graphics->nativeGraphics : NULL,
- &height
- ));
- return height;
-}
-
-
-#ifdef DCR_USE_NEW_125467
-inline REAL
-Font::GetHeight(IN REAL dpi = 0) const
-{
- REAL height;
- SetStatus(DllExports::GdipGetFontHeightGivenDPI(nativeFont, dpi, &height));
- return height;
-}
-#endif
-
-
-// protected method
-inline
-Font::Font(IN GpFont* font,
- IN Status status)
-{
- lastResult = status;
- SetNativeFont(font);
-}
-
-// protected method
-inline VOID
-Font::SetNativeFont(GpFont *Font)
-{
- nativeFont = Font;
-}
-
-inline Status
-Font::GetLastStatus(void) const
-{
- return lastResult;
-}
-
-// protected method
-inline Status
-Font::SetStatus(IN Status status) const
-{
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
-}
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusFont.h
+*
+* Abstract:
+*
+* Font related declarations
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSFONT_H
+#define _GDIPLUSFONT_H
+
+inline
+Font::Font(IN HDC hdc)
+{
+ GpFont *font = NULL;
+ lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) lastResult >= 10)
+ lastResult = NotFound;
+#endif
+
+ SetNativeFont(font);
+}
+
+#ifdef DCR_USE_NEW_127084
+inline
+Font::Font(IN HDC hdc,
+ IN const HFONT hfont)
+{
+ GpFont *font = NULL;
+
+ if (hfont)
+ {
+ LOGFONTA lf;
+
+ if(GetObjectA(hfont, sizeof(LOGFONTA), &lf))
+ lastResult = DllExports::GdipCreateFontFromLogfontA(hdc, &lf, &font);
+ else
+ lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
+ }
+ else
+ {
+ lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
+ }
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) lastResult >= 10)
+ lastResult = NotFound;
+#endif
+
+ SetNativeFont(font);
+}
+#endif
+
+inline
+Font::Font(IN HDC hdc,
+ IN const LOGFONTW* logfont)
+{
+ GpFont *font = NULL;
+ if (logfont)
+ {
+ lastResult = DllExports::GdipCreateFontFromLogfontW(hdc, logfont, &font);
+ }
+ else
+ {
+ lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
+ }
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) lastResult >= 10)
+ lastResult = NotFound;
+#endif
+
+ SetNativeFont(font);
+}
+
+inline
+Font::Font(IN HDC hdc,
+ IN const LOGFONTA* logfont)
+{
+ GpFont *font = NULL;
+
+ if (logfont)
+ {
+ lastResult = DllExports::GdipCreateFontFromLogfontA(hdc, logfont, &font);
+ }
+ else
+ {
+ lastResult = DllExports::GdipCreateFontFromDC(hdc, &font);
+ }
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) lastResult >= 10)
+ lastResult = NotFound;
+#endif
+
+ SetNativeFont(font);
+}
+
+inline
+Font::Font(
+ IN const FontFamily * family,
+ IN REAL emSize,
+ IN INT style,
+ IN Unit unit
+)
+{
+ GpFont *font = NULL;
+
+ lastResult = DllExports::GdipCreateFont(family ? family->nativeFamily : NULL,
+ emSize,
+ style,
+ unit,
+ &font);
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) lastResult >= 10)
+ lastResult = NotFound;
+#endif
+
+ SetNativeFont(font);
+}
+
+inline
+Font::Font(
+ IN const WCHAR * familyName,
+ IN REAL emSize,
+ IN INT style,
+ IN Unit unit,
+ IN const FontCollection * fontCollection
+)
+{
+ FontFamily family(familyName, fontCollection);
+
+ GpFont * font = NULL;
+
+ lastResult = family.GetLastStatus();
+
+ if (lastResult == Ok)
+ {
+ lastResult = DllExports::GdipCreateFont(family.nativeFamily,
+ emSize,
+ style,
+ unit,
+ &font);
+ }
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) lastResult >= 10)
+ lastResult = NotFound;
+#endif
+
+ SetNativeFont(font);
+}
+
+inline Status
+Font::GetLogFontA(IN const Graphics *g,
+ OUT LOGFONTA *logfontA) const
+{
+ return SetStatus(DllExports::GdipGetLogFontA(nativeFont, g ? g->nativeGraphics : NULL, logfontA));
+
+}
+
+inline Status
+Font::GetLogFontW(IN const Graphics *g,
+ OUT LOGFONTW *logfontW) const
+{
+ return SetStatus(DllExports::GdipGetLogFontW(nativeFont, g ? g->nativeGraphics : NULL, logfontW));
+}
+
+
+inline Font*
+Font::Clone() const
+{
+ GpFont *cloneFont = NULL;
+
+ SetStatus(DllExports::GdipCloneFont(nativeFont, &cloneFont));
+
+ return new Font(cloneFont, lastResult);
+}
+
+inline
+Font::~Font()
+{
+ DllExports::GdipDeleteFont(nativeFont);
+}
+
+// Operations
+
+inline BOOL
+Font::IsAvailable() const
+{
+ return (nativeFont ? TRUE : FALSE);
+}
+
+inline Status
+Font::GetFamily(OUT FontFamily *family) const
+{
+ if (family == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ Status status = DllExports::GdipGetFamily(nativeFont, &(family->nativeFamily));
+ family->SetStatus(status);
+
+ return SetStatus(status);
+}
+
+inline INT
+Font::GetStyle() const
+{
+ INT style;
+
+ SetStatus(DllExports::GdipGetFontStyle(nativeFont, &style));
+
+ return style;
+}
+
+inline REAL
+Font::GetSize() const
+{
+ REAL size;
+ SetStatus(DllExports::GdipGetFontSize(nativeFont, &size));
+ return size;
+}
+
+inline Unit
+Font::GetUnit() const
+{
+ Unit unit;
+ SetStatus(DllExports::GdipGetFontUnit(nativeFont, &unit));
+ return unit;
+}
+
+inline REAL
+Font::GetHeight(IN const Graphics *graphics) const
+{
+ REAL height;
+ SetStatus(DllExports::GdipGetFontHeight(
+ nativeFont,
+ graphics ? graphics->nativeGraphics : NULL,
+ &height
+ ));
+ return height;
+}
+
+
+#ifdef DCR_USE_NEW_125467
+inline REAL
+Font::GetHeight(IN REAL dpi = 0) const
+{
+ REAL height;
+ SetStatus(DllExports::GdipGetFontHeightGivenDPI(nativeFont, dpi, &height));
+ return height;
+}
+#endif
+
+
+// protected method
+inline
+Font::Font(IN GpFont* font,
+ IN Status status)
+{
+ lastResult = status;
+ SetNativeFont(font);
+}
+
+// protected method
+inline VOID
+Font::SetNativeFont(GpFont *Font)
+{
+ nativeFont = Font;
+}
+
+inline Status
+Font::GetLastStatus(void) const
+{
+ return lastResult;
+}
+
+// protected method
+inline Status
+Font::SetStatus(IN Status status) const
+{
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+}
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusFontCollection.h b/core/src/fxge/Microsoft SDK/include/GdiPlusFontCollection.h
index d2257ba456..2f3351c95b 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusFontCollection.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusFontCollection.h
@@ -1,149 +1,149 @@
-/**************************************************************************\
-*
-* Copyright (c) 2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusFontCollection.h
-*
-* Abstract:
-*
-* Font collections (Installed and Private)
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSFONTCOLL_H
-#define _GDIPLUSFONTCOLL_H
-
-inline
-FontCollection::FontCollection()
-{
- nativeFontCollection = NULL;
-}
-
-inline
-FontCollection::~FontCollection()
-{
-}
-
-inline INT
-FontCollection::GetFamilyCount() const
-{
- INT numFound = 0;
-
- lastResult = DllExports::GdipGetFontCollectionFamilyCount(
- nativeFontCollection, &numFound);
-
-
-
- return numFound;
-}
-
-inline Status
-FontCollection::GetFamilies(
- IN INT numSought,
- OUT FontFamily * gpfamilies,
- OUT INT * numFound
-) const
-{
- if (numSought <= 0 || gpfamilies == NULL || numFound == NULL)
- {
- return SetStatus(InvalidParameter);
- }
- *numFound = 0;
- GpFontFamily **nativeFamilyList = new GpFontFamily*[numSought];
-
- if (nativeFamilyList == NULL)
- {
- return SetStatus(OutOfMemory);
- }
-
- Status status = SetStatus(DllExports::GdipGetFontCollectionFamilyList(
- nativeFontCollection,
- numSought,
- nativeFamilyList,
- numFound
- ));
- if (status == Ok)
- {
- for (INT i = 0; i < *numFound; i++)
- {
- DllExports::GdipCloneFontFamily(nativeFamilyList[i],
- &gpfamilies[i].nativeFamily);
- }
- }
-
- delete [] nativeFamilyList;
-
- return status;
-}
-
-inline Status FontCollection::GetLastStatus () const
-{
- return lastResult;
-}
-
-// protected method
-inline Status
-FontCollection::SetStatus(IN Status status) const
-{
- lastResult = status;
- return lastResult;
-}
-
-inline
-InstalledFontCollection::InstalledFontCollection()
-{
- nativeFontCollection = NULL;
- lastResult = DllExports::GdipNewInstalledFontCollection(&nativeFontCollection);
-}
-
-inline
-InstalledFontCollection::~InstalledFontCollection()
-{
-}
-
-#ifndef DCR_USE_NEW_235072
-inline Status
-InstalledFontCollection::InstallFontFile(IN const WCHAR* filename)
-{
- return SetStatus(DllExports::GdipInstallFontFile(nativeFontCollection, filename));
-}
-
-inline Status
-InstalledFontCollection::UninstallFontFile(IN const WCHAR* filename)
-{
- return SetStatus(DllExports::GdipUninstallFontFile(nativeFontCollection, filename));
-}
-#endif
-
-inline
-PrivateFontCollection::PrivateFontCollection()
-{
- nativeFontCollection = NULL;
- lastResult = DllExports::GdipNewPrivateFontCollection(&nativeFontCollection);
-}
-
-inline
-PrivateFontCollection::~PrivateFontCollection()
-{
- DllExports::GdipDeletePrivateFontCollection(&nativeFontCollection);
-}
-
-inline Status
-PrivateFontCollection::AddFontFile(IN const WCHAR* filename)
-{
- return SetStatus(DllExports::GdipPrivateAddFontFile(nativeFontCollection, filename));
-}
-
-inline Status
-PrivateFontCollection::AddMemoryFont(IN const void* memory,
- IN INT length)
-{
- return SetStatus(DllExports::GdipPrivateAddMemoryFont(
- nativeFontCollection,
- memory,
- length));
-}
-
-#endif // _GDIPLUSFONTCOLL_H
+/**************************************************************************\
+*
+* Copyright (c) 2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusFontCollection.h
+*
+* Abstract:
+*
+* Font collections (Installed and Private)
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSFONTCOLL_H
+#define _GDIPLUSFONTCOLL_H
+
+inline
+FontCollection::FontCollection()
+{
+ nativeFontCollection = NULL;
+}
+
+inline
+FontCollection::~FontCollection()
+{
+}
+
+inline INT
+FontCollection::GetFamilyCount() const
+{
+ INT numFound = 0;
+
+ lastResult = DllExports::GdipGetFontCollectionFamilyCount(
+ nativeFontCollection, &numFound);
+
+
+
+ return numFound;
+}
+
+inline Status
+FontCollection::GetFamilies(
+ IN INT numSought,
+ OUT FontFamily * gpfamilies,
+ OUT INT * numFound
+) const
+{
+ if (numSought <= 0 || gpfamilies == NULL || numFound == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+ *numFound = 0;
+ GpFontFamily **nativeFamilyList = new GpFontFamily*[numSought];
+
+ if (nativeFamilyList == NULL)
+ {
+ return SetStatus(OutOfMemory);
+ }
+
+ Status status = SetStatus(DllExports::GdipGetFontCollectionFamilyList(
+ nativeFontCollection,
+ numSought,
+ nativeFamilyList,
+ numFound
+ ));
+ if (status == Ok)
+ {
+ for (INT i = 0; i < *numFound; i++)
+ {
+ DllExports::GdipCloneFontFamily(nativeFamilyList[i],
+ &gpfamilies[i].nativeFamily);
+ }
+ }
+
+ delete [] nativeFamilyList;
+
+ return status;
+}
+
+inline Status FontCollection::GetLastStatus () const
+{
+ return lastResult;
+}
+
+// protected method
+inline Status
+FontCollection::SetStatus(IN Status status) const
+{
+ lastResult = status;
+ return lastResult;
+}
+
+inline
+InstalledFontCollection::InstalledFontCollection()
+{
+ nativeFontCollection = NULL;
+ lastResult = DllExports::GdipNewInstalledFontCollection(&nativeFontCollection);
+}
+
+inline
+InstalledFontCollection::~InstalledFontCollection()
+{
+}
+
+#ifndef DCR_USE_NEW_235072
+inline Status
+InstalledFontCollection::InstallFontFile(IN const WCHAR* filename)
+{
+ return SetStatus(DllExports::GdipInstallFontFile(nativeFontCollection, filename));
+}
+
+inline Status
+InstalledFontCollection::UninstallFontFile(IN const WCHAR* filename)
+{
+ return SetStatus(DllExports::GdipUninstallFontFile(nativeFontCollection, filename));
+}
+#endif
+
+inline
+PrivateFontCollection::PrivateFontCollection()
+{
+ nativeFontCollection = NULL;
+ lastResult = DllExports::GdipNewPrivateFontCollection(&nativeFontCollection);
+}
+
+inline
+PrivateFontCollection::~PrivateFontCollection()
+{
+ DllExports::GdipDeletePrivateFontCollection(&nativeFontCollection);
+}
+
+inline Status
+PrivateFontCollection::AddFontFile(IN const WCHAR* filename)
+{
+ return SetStatus(DllExports::GdipPrivateAddFontFile(nativeFontCollection, filename));
+}
+
+inline Status
+PrivateFontCollection::AddMemoryFont(IN const void* memory,
+ IN INT length)
+{
+ return SetStatus(DllExports::GdipPrivateAddMemoryFont(
+ nativeFontCollection,
+ memory,
+ length));
+}
+
+#endif // _GDIPLUSFONTCOLL_H
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusFontFamily.h b/core/src/fxge/Microsoft SDK/include/GdiPlusFontFamily.h
index ef2f3dde9b..076e1572ac 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusFontFamily.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusFontFamily.h
@@ -1,271 +1,271 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusFontFamily.h
-*
-* Abstract:
-*
-* Font family API related declarations
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUS_FONT_FAMILY_H
-#define _GDIPLUS_FONT_FAMILY_H
-
-inline
-FontFamily::FontFamily() :
- nativeFamily (NULL),
- lastResult (Ok)
-{
-}
-
-inline
-FontFamily::FontFamily(
- IN const WCHAR* name,
- IN const FontCollection* fontCollection
-)
-{
- nativeFamily = NULL;
- lastResult = DllExports::GdipCreateFontFamilyFromName(
- name,
- fontCollection ? fontCollection->nativeFontCollection : NULL,
- &nativeFamily
- );
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) lastResult >= 10)
- lastResult = NotFound;
-#endif
-}
-
-// private method
-inline
-FontFamily::FontFamily(
- IN GpFontFamily *nativeOrig,
- IN Status status
-)
-{
- lastResult = status;
- nativeFamily = nativeOrig;
-}
-
-// Generic font family access
-
-inline const FontFamily *
-FontFamily::GenericSansSerif()
-{
- if (GenericSansSerifFontFamily != NULL)
- {
- return GenericSansSerifFontFamily;
- }
-
- GenericSansSerifFontFamily =
- (FontFamily*) GenericSansSerifFontFamilyBuffer;
-
- GenericSansSerifFontFamily->lastResult =
- DllExports::GdipGetGenericFontFamilySansSerif(
- &(GenericSansSerifFontFamily->nativeFamily)
- );
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) GenericSansSerifFontFamily->lastResult >= 10)
- GenericSansSerifFontFamily->lastResult = NotFound;
-#endif
-
- return GenericSansSerifFontFamily;
-}
-
-inline const FontFamily *
-FontFamily::GenericSerif()
-{
- if (GenericSerifFontFamily != NULL)
- {
- return GenericSerifFontFamily;
- }
-
- GenericSerifFontFamily =
- (FontFamily*) GenericSerifFontFamilyBuffer;
-
- GenericSerifFontFamily->lastResult =
- DllExports::GdipGetGenericFontFamilySerif(
- &(GenericSerifFontFamily->nativeFamily)
- );
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) GenericSerifFontFamily->lastResult >= 10)
- GenericSerifFontFamily->lastResult = NotFound;
-#endif
-
- return GenericSerifFontFamily;
-}
-
-inline const FontFamily *
-FontFamily::GenericMonospace()
-{
- if (GenericMonospaceFontFamily != NULL)
- {
- return GenericMonospaceFontFamily;
- }
-
- GenericMonospaceFontFamily =
- (FontFamily*) GenericMonospaceFontFamilyBuffer;
-
- GenericMonospaceFontFamily->lastResult =
- DllExports::GdipGetGenericFontFamilyMonospace(
- &(GenericMonospaceFontFamily->nativeFamily)
- );
-
-#ifndef DCR_USE_NEW_135429
- if ((INT) GenericMonospaceFontFamily->lastResult >= 10)
- GenericMonospaceFontFamily->lastResult = NotFound;
-#endif
-
- return GenericMonospaceFontFamily;
-}
-
-inline FontFamily::~FontFamily()
-{
- DllExports::GdipDeleteFontFamily (nativeFamily);
-}
-
-inline FontFamily *
-FontFamily::Clone() const
-{
- GpFontFamily * clonedFamily = NULL;
-
- SetStatus(DllExports::GdipCloneFontFamily (nativeFamily, &clonedFamily));
-
- return new FontFamily(clonedFamily, lastResult);
-}
-
-inline Status
-FontFamily::GetFamilyName(
- IN WCHAR name[LF_FACESIZE],
- IN LANGID language
-) const
-{
- return SetStatus(DllExports::GdipGetFamilyName(nativeFamily,
- name,
- language));
-}
-
-inline BOOL
-FontFamily::IsStyleAvailable(IN INT style) const
-{
- BOOL StyleAvailable;
- Status status;
-
- status = SetStatus(DllExports::GdipIsStyleAvailable(nativeFamily, style, &StyleAvailable));
-
- if (status != Ok)
- StyleAvailable = FALSE;
-
- return StyleAvailable;
-}
-
-
-inline UINT16
-FontFamily::GetEmHeight(IN INT style) const
-{
- UINT16 EmHeight;
-
- SetStatus(DllExports::GdipGetEmHeight(nativeFamily, style, &EmHeight));
-
- return EmHeight;
-}
-
-inline UINT16
-FontFamily::GetCellAscent(IN INT style) const
-{
- UINT16 CellAscent;
-
- SetStatus(DllExports::GdipGetCellAscent(nativeFamily, style, &CellAscent));
-
- return CellAscent;
-}
-
-inline UINT16
-FontFamily::GetCellDescent(IN INT style) const
-{
- UINT16 CellDescent;
-
- SetStatus(DllExports::GdipGetCellDescent(nativeFamily, style, &CellDescent));
-
- return CellDescent;
-}
-
-
-inline UINT16
-FontFamily::GetLineSpacing(IN INT style) const
-{
- UINT16 LineSpacing;
-
- SetStatus(DllExports::GdipGetLineSpacing(nativeFamily, style, &LineSpacing));
-
- return LineSpacing;
-
-}
-
-#ifdef TEXTV2
-
-// The following APIs return data from the font OS/2 table
-
-inline INT16
-FontFamily::GetTypographicAscent(IN INT style) const
-{
- INT16 TypographicAscent;
-
- SetStatus(DllExports::GdipGetTypographicAscent(nativeFamily, style, &TypographicAscent));
-
- return TypographicAscent;
-}
-
-inline INT16
-FontFamily::GetTypographicDescent(IN INT style) const
-{
- INT16 TypographicDescent;
-
- SetStatus(DllExports::GdipGetTypographicDescent(nativeFamily, style, &TypographicDescent));
-
- return TypographicDescent;
-}
-
-inline INT16
-FontFamily::GetTypographicLineGap(IN INT style) const
-{
- INT16 TypographicLineGap;
-
- SetStatus(DllExports::GdipGetTypographicLineGap(nativeFamily, style, &TypographicLineGap));
-
- return TypographicLineGap;
-}
-
-#endif
-
-///////////////////////////////////////////////////////////
-
-// GetLastStatus - return last error code and clear error code
-
-inline Status
-FontFamily::GetLastStatus() const
-{
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
-}
-
-// protected method
-inline Status
-FontFamily::SetStatus(Status status) const
-{
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
-}
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusFontFamily.h
+*
+* Abstract:
+*
+* Font family API related declarations
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUS_FONT_FAMILY_H
+#define _GDIPLUS_FONT_FAMILY_H
+
+inline
+FontFamily::FontFamily() :
+ nativeFamily (NULL),
+ lastResult (Ok)
+{
+}
+
+inline
+FontFamily::FontFamily(
+ IN const WCHAR* name,
+ IN const FontCollection* fontCollection
+)
+{
+ nativeFamily = NULL;
+ lastResult = DllExports::GdipCreateFontFamilyFromName(
+ name,
+ fontCollection ? fontCollection->nativeFontCollection : NULL,
+ &nativeFamily
+ );
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) lastResult >= 10)
+ lastResult = NotFound;
+#endif
+}
+
+// private method
+inline
+FontFamily::FontFamily(
+ IN GpFontFamily *nativeOrig,
+ IN Status status
+)
+{
+ lastResult = status;
+ nativeFamily = nativeOrig;
+}
+
+// Generic font family access
+
+inline const FontFamily *
+FontFamily::GenericSansSerif()
+{
+ if (GenericSansSerifFontFamily != NULL)
+ {
+ return GenericSansSerifFontFamily;
+ }
+
+ GenericSansSerifFontFamily =
+ (FontFamily*) GenericSansSerifFontFamilyBuffer;
+
+ GenericSansSerifFontFamily->lastResult =
+ DllExports::GdipGetGenericFontFamilySansSerif(
+ &(GenericSansSerifFontFamily->nativeFamily)
+ );
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) GenericSansSerifFontFamily->lastResult >= 10)
+ GenericSansSerifFontFamily->lastResult = NotFound;
+#endif
+
+ return GenericSansSerifFontFamily;
+}
+
+inline const FontFamily *
+FontFamily::GenericSerif()
+{
+ if (GenericSerifFontFamily != NULL)
+ {
+ return GenericSerifFontFamily;
+ }
+
+ GenericSerifFontFamily =
+ (FontFamily*) GenericSerifFontFamilyBuffer;
+
+ GenericSerifFontFamily->lastResult =
+ DllExports::GdipGetGenericFontFamilySerif(
+ &(GenericSerifFontFamily->nativeFamily)
+ );
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) GenericSerifFontFamily->lastResult >= 10)
+ GenericSerifFontFamily->lastResult = NotFound;
+#endif
+
+ return GenericSerifFontFamily;
+}
+
+inline const FontFamily *
+FontFamily::GenericMonospace()
+{
+ if (GenericMonospaceFontFamily != NULL)
+ {
+ return GenericMonospaceFontFamily;
+ }
+
+ GenericMonospaceFontFamily =
+ (FontFamily*) GenericMonospaceFontFamilyBuffer;
+
+ GenericMonospaceFontFamily->lastResult =
+ DllExports::GdipGetGenericFontFamilyMonospace(
+ &(GenericMonospaceFontFamily->nativeFamily)
+ );
+
+#ifndef DCR_USE_NEW_135429
+ if ((INT) GenericMonospaceFontFamily->lastResult >= 10)
+ GenericMonospaceFontFamily->lastResult = NotFound;
+#endif
+
+ return GenericMonospaceFontFamily;
+}
+
+inline FontFamily::~FontFamily()
+{
+ DllExports::GdipDeleteFontFamily (nativeFamily);
+}
+
+inline FontFamily *
+FontFamily::Clone() const
+{
+ GpFontFamily * clonedFamily = NULL;
+
+ SetStatus(DllExports::GdipCloneFontFamily (nativeFamily, &clonedFamily));
+
+ return new FontFamily(clonedFamily, lastResult);
+}
+
+inline Status
+FontFamily::GetFamilyName(
+ IN WCHAR name[LF_FACESIZE],
+ IN LANGID language
+) const
+{
+ return SetStatus(DllExports::GdipGetFamilyName(nativeFamily,
+ name,
+ language));
+}
+
+inline BOOL
+FontFamily::IsStyleAvailable(IN INT style) const
+{
+ BOOL StyleAvailable;
+ Status status;
+
+ status = SetStatus(DllExports::GdipIsStyleAvailable(nativeFamily, style, &StyleAvailable));
+
+ if (status != Ok)
+ StyleAvailable = FALSE;
+
+ return StyleAvailable;
+}
+
+
+inline UINT16
+FontFamily::GetEmHeight(IN INT style) const
+{
+ UINT16 EmHeight;
+
+ SetStatus(DllExports::GdipGetEmHeight(nativeFamily, style, &EmHeight));
+
+ return EmHeight;
+}
+
+inline UINT16
+FontFamily::GetCellAscent(IN INT style) const
+{
+ UINT16 CellAscent;
+
+ SetStatus(DllExports::GdipGetCellAscent(nativeFamily, style, &CellAscent));
+
+ return CellAscent;
+}
+
+inline UINT16
+FontFamily::GetCellDescent(IN INT style) const
+{
+ UINT16 CellDescent;
+
+ SetStatus(DllExports::GdipGetCellDescent(nativeFamily, style, &CellDescent));
+
+ return CellDescent;
+}
+
+
+inline UINT16
+FontFamily::GetLineSpacing(IN INT style) const
+{
+ UINT16 LineSpacing;
+
+ SetStatus(DllExports::GdipGetLineSpacing(nativeFamily, style, &LineSpacing));
+
+ return LineSpacing;
+
+}
+
+#ifdef TEXTV2
+
+// The following APIs return data from the font OS/2 table
+
+inline INT16
+FontFamily::GetTypographicAscent(IN INT style) const
+{
+ INT16 TypographicAscent;
+
+ SetStatus(DllExports::GdipGetTypographicAscent(nativeFamily, style, &TypographicAscent));
+
+ return TypographicAscent;
+}
+
+inline INT16
+FontFamily::GetTypographicDescent(IN INT style) const
+{
+ INT16 TypographicDescent;
+
+ SetStatus(DllExports::GdipGetTypographicDescent(nativeFamily, style, &TypographicDescent));
+
+ return TypographicDescent;
+}
+
+inline INT16
+FontFamily::GetTypographicLineGap(IN INT style) const
+{
+ INT16 TypographicLineGap;
+
+ SetStatus(DllExports::GdipGetTypographicLineGap(nativeFamily, style, &TypographicLineGap));
+
+ return TypographicLineGap;
+}
+
+#endif
+
+///////////////////////////////////////////////////////////
+
+// GetLastStatus - return last error code and clear error code
+
+inline Status
+FontFamily::GetLastStatus() const
+{
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+}
+
+// protected method
+inline Status
+FontFamily::SetStatus(Status status) const
+{
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+}
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusGpStubs.h b/core/src/fxge/Microsoft SDK/include/GdiPlusGpStubs.h
index 121288de57..4f6066ccef 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusGpStubs.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusGpStubs.h
@@ -1,107 +1,107 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusGpStubs.h
-*
-* Abstract:
-*
-* GDI+ Native C++ public header file
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSGPSTUBS_H
-#define _GDIPLUSGPSTUBS_H
-
-//---------------------------------------------------------------------------
-// GDI+ classes for forward reference
-//---------------------------------------------------------------------------
-
-class Graphics;
-class Pen;
-class Brush;
-class Matrix;
-class Bitmap;
-class Metafile;
-class GraphicsPath;
-class PathIterator;
-class Region;
-class Image;
-class TextureBrush;
-class HatchBrush;
-class SolidBrush;
-class LinearGradientBrush;
-class PathGradientBrush;
-class Font;
-class FontFamily;
-class FontCollection;
-class InstalledFontCollection;
-class PrivateFontCollection;
-class ImageAttributes;
-class CachedBitmap;
-
-//---------------------------------------------------------------------------
-// Internal GDI+ classes for internal type checking
-//---------------------------------------------------------------------------
-class GpGraphics {};
-
-class GpBrush {};
-class GpTexture : public GpBrush {};
-class GpSolidFill : public GpBrush {};
-class GpLineGradient : public GpBrush {};
-class GpPathGradient : public GpBrush {};
-class GpHatch : public GpBrush {};
-
-class GpPen {};
-class GpCustomLineCap {};
-class GpAdjustableArrowCap : public GpCustomLineCap {};
-
-class GpImage {};
-class GpBitmap : public GpImage {};
-class GpMetafile : public GpImage {};
-class GpImageAttributes {};
-
-class GpPath {};
-class GpRegion {};
-class GpPathIterator {};
-
-class GpFontFamily {};
-class GpFont {};
-class GpStringFormat {};
-class GpFontCollection {};
-class GpInstalledFontCollection : public GpFontCollection {};
-class GpPrivateFontCollection : public GpFontCollection {};
-
-class GpCachedBitmap;
-
-typedef Status GpStatus;
-typedef FillMode GpFillMode;
-typedef WrapMode GpWrapMode;
-typedef Unit GpUnit;
-typedef CoordinateSpace GpCoordinateSpace;
-typedef PointF GpPointF;
-typedef Point GpPoint;
-typedef RectF GpRectF;
-typedef Rect GpRect;
-typedef SizeF GpSizeF;
-typedef HatchStyle GpHatchStyle;
-typedef DashStyle GpDashStyle;
-typedef LineCap GpLineCap;
-typedef DashCap GpDashCap;
-
-
-typedef PenAlignment GpPenAlignment;
-
-typedef LineJoin GpLineJoin;
-typedef PenType GpPenType;
-
-typedef Matrix GpMatrix;
-typedef BrushType GpBrushType;
-typedef MatrixOrder GpMatrixOrder;
-typedef FlushIntention GpFlushIntention;
-typedef PathData GpPathData;
-
-#endif // !_GDIPLUSGPSTUBS.HPP
-
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusGpStubs.h
+*
+* Abstract:
+*
+* GDI+ Native C++ public header file
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSGPSTUBS_H
+#define _GDIPLUSGPSTUBS_H
+
+//---------------------------------------------------------------------------
+// GDI+ classes for forward reference
+//---------------------------------------------------------------------------
+
+class Graphics;
+class Pen;
+class Brush;
+class Matrix;
+class Bitmap;
+class Metafile;
+class GraphicsPath;
+class PathIterator;
+class Region;
+class Image;
+class TextureBrush;
+class HatchBrush;
+class SolidBrush;
+class LinearGradientBrush;
+class PathGradientBrush;
+class Font;
+class FontFamily;
+class FontCollection;
+class InstalledFontCollection;
+class PrivateFontCollection;
+class ImageAttributes;
+class CachedBitmap;
+
+//---------------------------------------------------------------------------
+// Internal GDI+ classes for internal type checking
+//---------------------------------------------------------------------------
+class GpGraphics {};
+
+class GpBrush {};
+class GpTexture : public GpBrush {};
+class GpSolidFill : public GpBrush {};
+class GpLineGradient : public GpBrush {};
+class GpPathGradient : public GpBrush {};
+class GpHatch : public GpBrush {};
+
+class GpPen {};
+class GpCustomLineCap {};
+class GpAdjustableArrowCap : public GpCustomLineCap {};
+
+class GpImage {};
+class GpBitmap : public GpImage {};
+class GpMetafile : public GpImage {};
+class GpImageAttributes {};
+
+class GpPath {};
+class GpRegion {};
+class GpPathIterator {};
+
+class GpFontFamily {};
+class GpFont {};
+class GpStringFormat {};
+class GpFontCollection {};
+class GpInstalledFontCollection : public GpFontCollection {};
+class GpPrivateFontCollection : public GpFontCollection {};
+
+class GpCachedBitmap;
+
+typedef Status GpStatus;
+typedef FillMode GpFillMode;
+typedef WrapMode GpWrapMode;
+typedef Unit GpUnit;
+typedef CoordinateSpace GpCoordinateSpace;
+typedef PointF GpPointF;
+typedef Point GpPoint;
+typedef RectF GpRectF;
+typedef Rect GpRect;
+typedef SizeF GpSizeF;
+typedef HatchStyle GpHatchStyle;
+typedef DashStyle GpDashStyle;
+typedef LineCap GpLineCap;
+typedef DashCap GpDashCap;
+
+
+typedef PenAlignment GpPenAlignment;
+
+typedef LineJoin GpLineJoin;
+typedef PenType GpPenType;
+
+typedef Matrix GpMatrix;
+typedef BrushType GpBrushType;
+typedef MatrixOrder GpMatrixOrder;
+typedef FlushIntention GpFlushIntention;
+typedef PathData GpPathData;
+
+#endif // !_GDIPLUSGPSTUBS.HPP
+
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusGraphics.h b/core/src/fxge/Microsoft SDK/include/GdiPlusGraphics.h
index 7b39a6ea71..4e4e3dae12 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusGraphics.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusGraphics.h
@@ -1,2726 +1,2726 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusGraphics.h
-*
-* Abstract:
-*
-* Declarations for Graphics class
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSGRAPHICS_H
-#define _GDIPLUSGRAPHICS_H
-
-/**
- * Represent a graphics context
- */
-class Graphics : public GdiplusBase
-{
-public:
- friend class Region;
- friend class GraphicsPath;
- friend class Image;
- friend class Bitmap;
- friend class Metafile;
- friend class Font;
- friend class FontFamily;
- friend class FontCollection;
- friend class CachedBitmap;
-
- // Get a graphics context from an existing Win32 HDC or HWND
- static Graphics* FromHDC(IN HDC hdc)
- {
- return new Graphics(hdc);
- }
-
- static Graphics* FromHDC(IN HDC hdc,
- IN HANDLE hdevice)
- {
- return new Graphics(hdc, hdevice);
- }
-
- static Graphics* FromHWND(IN HWND hwnd,
- IN BOOL icm = FALSE)
- {
- return new Graphics(hwnd, icm);
- }
-
- static Graphics* FromImage(IN Image *image)
- {
- return new Graphics(image);
- }
-
- Graphics(IN HDC hdc)
- {
- GpGraphics *graphics = NULL;
-
- lastResult = DllExports::GdipCreateFromHDC(hdc, &graphics);
-
- SetNativeGraphics(graphics);
- }
-
- Graphics(IN HDC hdc,
- IN HANDLE hdevice)
- {
- GpGraphics *graphics = NULL;
-
- lastResult = DllExports::GdipCreateFromHDC2(hdc, hdevice, &graphics);
-
- SetNativeGraphics(graphics);
- }
-
- Graphics(IN HWND hwnd,
- IN BOOL icm = FALSE)
- {
- GpGraphics *graphics = NULL;
-
- if (icm)
- {
- lastResult = DllExports::GdipCreateFromHWNDICM(hwnd, &graphics);
- }
- else
- {
- lastResult = DllExports::GdipCreateFromHWND(hwnd, &graphics);
- }
-
- SetNativeGraphics(graphics);
- }
-
- Graphics(IN Image* image)
- {
- GpGraphics *graphics = NULL;
-
- if (image != NULL)
- {
- lastResult = DllExports::GdipGetImageGraphicsContext(
- image->nativeImage, &graphics);
- }
- SetNativeGraphics(graphics);
- }
-
- ~Graphics()
- {
- DllExports::GdipDeleteGraphics(nativeGraphics);
- }
-
- VOID Flush(IN FlushIntention intention = FlushIntentionFlush)
- {
- DllExports::GdipFlush(nativeGraphics, intention);
- }
-
- //------------------------------------------------------------------------
- // Interop methods
- //------------------------------------------------------------------------
-
- // Locks the graphics until ReleaseDC is called
- HDC GetHDC()
- {
- HDC hdc = NULL;
-
- SetStatus(DllExports::GdipGetDC(nativeGraphics, &hdc));
-
- return hdc;
- }
-
- VOID ReleaseHDC(IN HDC hdc)
- {
- SetStatus(DllExports::GdipReleaseDC(nativeGraphics, hdc));
- }
-
- //------------------------------------------------------------------------
- // Rendering modes
- //------------------------------------------------------------------------
-
- Status SetRenderingOrigin(IN INT x, IN INT y)
- {
- return SetStatus(
- DllExports::GdipSetRenderingOrigin(
- nativeGraphics, x, y
- )
- );
- }
-
- Status GetRenderingOrigin(OUT INT *x, OUT INT *y) const
- {
- return SetStatus(
- DllExports::GdipGetRenderingOrigin(
- nativeGraphics, x, y
- )
- );
- }
-
- Status SetCompositingMode(IN CompositingMode compositingMode)
- {
- return SetStatus(DllExports::GdipSetCompositingMode(nativeGraphics,
- compositingMode));
- }
-
- CompositingMode GetCompositingMode() const
- {
- CompositingMode mode;
-
- SetStatus(DllExports::GdipGetCompositingMode(nativeGraphics,
- &mode));
-
- return mode;
- }
-
- Status SetCompositingQuality(IN CompositingQuality compositingQuality)
- {
- return SetStatus(DllExports::GdipSetCompositingQuality(
- nativeGraphics,
- compositingQuality));
- }
-
- CompositingQuality GetCompositingQuality() const
- {
- CompositingQuality quality;
-
- SetStatus(DllExports::GdipGetCompositingQuality(
- nativeGraphics,
- &quality));
-
- return quality;
- }
-
- Status SetTextRenderingHint(IN TextRenderingHint newMode)
- {
-#ifndef DCR_USE_NEW_186764
- /* temporarly set the high bit to warn that we are using the new definition for the flag */
- newMode = (TextRenderingHint) (newMode | 0x0f000);
-#endif // DCR_USE_NEW_186764
- return SetStatus(DllExports::GdipSetTextRenderingHint(nativeGraphics,
- newMode));
- }
-
- TextRenderingHint GetTextRenderingHint() const
- {
- TextRenderingHint hint;
-
- SetStatus(DllExports::GdipGetTextRenderingHint(nativeGraphics,
- &hint));
-
- return hint;
- }
-
-#ifdef DCR_USE_NEW_188922
- Status SetTextContrast(IN UINT contrast)
- {
- return SetStatus(DllExports::GdipSetTextContrast(nativeGraphics,
- contrast));
- }
-
- UINT GetTextContrast() const
- {
- UINT contrast;
-
- SetStatus(DllExports::GdipGetTextContrast(nativeGraphics,
- &contrast));
-
- return contrast;
- }
-#else
- Status SetTextGammaValue(IN UINT gammaValue)
- {
- return SetStatus(DllExports::GdipSetTextGammaValue(nativeGraphics,
- gammaValue));
- }
-
- UINT GetTextGammaValue() const
- {
- UINT gammaValue;
-
- SetStatus(DllExports::GdipGetTextGammaValue(nativeGraphics,
- &gammaValue));
-
- return gammaValue;
- }
-
-#endif // DCR_USE_NEW_188922
-
-
- InterpolationMode GetInterpolationMode() const
- {
- InterpolationMode mode = InterpolationModeInvalid;
-
- SetStatus(DllExports::GdipGetInterpolationMode(nativeGraphics,
- &mode));
-
- return mode;
- }
-
- Status SetInterpolationMode(IN InterpolationMode interpolationMode)
- {
- return SetStatus(DllExports::GdipSetInterpolationMode(nativeGraphics,
- interpolationMode));
- }
-
- SmoothingMode GetSmoothingMode() const
- {
- SmoothingMode smoothingMode = SmoothingModeInvalid;
-
- SetStatus(DllExports::GdipGetSmoothingMode(nativeGraphics,
- &smoothingMode));
-
- return smoothingMode;
- }
-
- Status SetSmoothingMode(IN SmoothingMode smoothingMode)
- {
- return SetStatus(DllExports::GdipSetSmoothingMode(nativeGraphics,
- smoothingMode));
- }
-
- PixelOffsetMode GetPixelOffsetMode() const
- {
- PixelOffsetMode pixelOffsetMode = PixelOffsetModeInvalid;
-
- SetStatus(DllExports::GdipGetPixelOffsetMode(nativeGraphics,
- &pixelOffsetMode));
-
- return pixelOffsetMode;
- }
-
- Status SetPixelOffsetMode(IN PixelOffsetMode pixelOffsetMode)
- {
- return SetStatus(DllExports::GdipSetPixelOffsetMode(nativeGraphics,
- pixelOffsetMode));
- }
-
- //------------------------------------------------------------------------
- // Manipulate the current world transform
- //------------------------------------------------------------------------
-
- Status SetTransform(IN const Matrix* matrix)
- {
- return SetStatus(DllExports::GdipSetWorldTransform(nativeGraphics,
- matrix->nativeMatrix));
- }
- Status ResetTransform()
- {
- return SetStatus(DllExports::GdipResetWorldTransform(nativeGraphics));
- }
-
- Status MultiplyTransform(IN const Matrix* matrix,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipMultiplyWorldTransform(nativeGraphics,
- matrix->nativeMatrix,
- order));
- }
-
- Status TranslateTransform(IN REAL dx,
- IN REAL dy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipTranslateWorldTransform(nativeGraphics,
- dx, dy, order));
- }
-
- Status ScaleTransform(IN REAL sx,
- IN REAL sy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipScaleWorldTransform(nativeGraphics,
- sx, sy, order));
- }
-
- Status RotateTransform(IN REAL angle,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipRotateWorldTransform(nativeGraphics,
- angle, order));
- }
-
- /**
- * Return the current world transform
- */
-
- Status GetTransform(OUT Matrix* matrix) const
- {
- return SetStatus(DllExports::GdipGetWorldTransform(nativeGraphics,
- matrix->nativeMatrix));
- }
-
- /**
- * Manipulate the current page transform
- */
-
- Status SetPageUnit(IN Unit unit)
- {
- return SetStatus(DllExports::GdipSetPageUnit(nativeGraphics,
- unit));
- }
-
- Status SetPageScale(IN REAL scale)
- {
- return SetStatus(DllExports::GdipSetPageScale(nativeGraphics,
- scale));
- }
-
- /**
- * Retrieve the current page transform information
- * notes @ these are atomic
- */
- Unit GetPageUnit() const
- {
- Unit unit;
-
- SetStatus(DllExports::GdipGetPageUnit(nativeGraphics, &unit));
-
- return unit;
- }
-
- REAL GetPageScale() const
- {
- REAL scale;
-
- SetStatus(DllExports::GdipGetPageScale(nativeGraphics, &scale));
-
- return scale;
- }
-
- REAL GetDpiX() const
- {
- REAL dpi;
-
- SetStatus(DllExports::GdipGetDpiX(nativeGraphics, &dpi));
-
- return dpi;
- }
-
- REAL GetDpiY() const
- {
- REAL dpi;
-
- SetStatus(DllExports::GdipGetDpiY(nativeGraphics, &dpi));
-
- return dpi;
- }
-
- /**
- * Transform points in the current graphics context
- */
- // float version
- Status TransformPoints(IN CoordinateSpace destSpace,
- IN CoordinateSpace srcSpace,
- IN OUT PointF* pts,
- IN INT count) const
- {
- return SetStatus(DllExports::GdipTransformPoints(nativeGraphics,
- destSpace,
- srcSpace,
- pts,
- count));
- }
-
- // integer version
- Status TransformPoints(IN CoordinateSpace destSpace,
- IN CoordinateSpace srcSpace,
- IN OUT Point* pts,
- IN INT count) const
- {
-
- return SetStatus(DllExports::GdipTransformPointsI(nativeGraphics,
- destSpace,
- srcSpace,
- pts,
- count));
- }
-
- //------------------------------------------------------------------------
- // GetNearestColor (for <= 8bpp surfaces)
- // Note: alpha is ignored
- //------------------------------------------------------------------------
- Status GetNearestColor(IN OUT Color* color) const
- {
- if (color == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- ARGB argb = color->GetValue();
-
- Status status = SetStatus(DllExports::GdipGetNearestColor(nativeGraphics, &argb));
-
- color->SetValue(argb);
-
- return status;
- }
-
- /**
- * Vector drawing methods
- *
- * @notes Do we need a set of methods that take
- * integer coordinate parameters?
- */
-
- // float version
- Status DrawLine(IN const Pen* pen,
- IN REAL x1,
- IN REAL y1,
- IN REAL x2,
- IN REAL y2)
- {
- return SetStatus(DllExports::GdipDrawLine(nativeGraphics,
- pen->nativePen, x1, y1, x2,
- y2));
- }
-
- Status DrawLine(IN const Pen* pen,
- IN const PointF& pt1,
- IN const PointF& pt2)
- {
- return DrawLine(pen, pt1.X, pt1.Y, pt2.X, pt2.Y);
- }
-
- Status DrawLines(IN const Pen* pen,
- IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawLines(nativeGraphics,
- pen->nativePen,
- points, count));
- }
-
- // int version
- Status DrawLine(IN const Pen* pen,
- IN INT x1,
- IN INT y1,
- IN INT x2,
- IN INT y2)
- {
- return SetStatus(DllExports::GdipDrawLineI(nativeGraphics,
- pen->nativePen,
- x1,
- y1,
- x2,
- y2));
- }
-
- Status DrawLine(IN const Pen* pen,
- IN const Point& pt1,
- IN const Point& pt2)
- {
- return DrawLine(pen,
- pt1.X,
- pt1.Y,
- pt2.X,
- pt2.Y);
- }
-
- Status DrawLines(IN const Pen* pen,
- IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawLinesI(nativeGraphics,
- pen->nativePen,
- points,
- count));
- }
-
- // float version
- Status DrawArc(IN const Pen* pen,
- IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipDrawArc(nativeGraphics,
- pen->nativePen,
- x,
- y,
- width,
- height,
- startAngle,
- sweepAngle));
- }
-
- Status DrawArc(IN const Pen* pen,
- IN const RectF& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return DrawArc(pen, rect.X, rect.Y, rect.Width, rect.Height,
- startAngle, sweepAngle);
- }
-
- // int version
- Status DrawArc(IN const Pen* pen,
- IN INT x,
- IN INT y,
- IN INT width,
- IN INT height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipDrawArcI(nativeGraphics,
- pen->nativePen,
- x,
- y,
- width,
- height,
- startAngle,
- sweepAngle));
- }
-
-
- Status DrawArc(IN const Pen* pen,
- IN const Rect& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return DrawArc(pen,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height,
- startAngle,
- sweepAngle);
- }
-
- // float version
- Status DrawBezier(IN const Pen* pen,
- IN REAL x1,
- IN REAL y1,
- IN REAL x2,
- IN REAL y2,
- IN REAL x3,
- IN REAL y3,
- IN REAL x4,
- IN REAL y4)
- {
- return SetStatus(DllExports::GdipDrawBezier(nativeGraphics,
- pen->nativePen, x1, y1,
- x2, y2, x3, y3, x4, y4));
- }
-
- Status DrawBezier(IN const Pen* pen,
- IN const PointF& pt1,
- IN const PointF& pt2,
- IN const PointF& pt3,
- IN const PointF& pt4)
- {
- return DrawBezier(pen,
- pt1.X,
- pt1.Y,
- pt2.X,
- pt2.Y,
- pt3.X,
- pt3.Y,
- pt4.X,
- pt4.Y);
- }
-
- Status DrawBeziers(IN const Pen* pen,
- IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawBeziers(nativeGraphics,
- pen->nativePen,
- points,
- count));
- }
-
- // int version
- Status DrawBezier(IN const Pen* pen,
- IN INT x1,
- IN INT y1,
- IN INT x2,
- IN INT y2,
- IN INT x3,
- IN INT y3,
- IN INT x4,
- IN INT y4)
- {
- return SetStatus(DllExports::GdipDrawBezierI(nativeGraphics,
- pen->nativePen,
- x1,
- y1,
- x2,
- y2,
- x3,
- y3,
- x4,
- y4));
- }
-
- Status DrawBezier(IN const Pen* pen,
- IN const Point& pt1,
- IN const Point& pt2,
- IN const Point& pt3,
- IN const Point& pt4)
- {
- return DrawBezier(pen,
- pt1.X,
- pt1.Y,
- pt2.X,
- pt2.Y,
- pt3.X,
- pt3.Y,
- pt4.X,
- pt4.Y);
- }
-
- Status DrawBeziers(IN const Pen* pen,
- IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawBeziersI(nativeGraphics,
- pen->nativePen,
- points,
- count));
- }
-
- // float version
- Status DrawRectangle(IN const Pen* pen,
- IN const RectF& rect)
- {
- return DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
- }
-
- Status DrawRectangle(IN const Pen* pen,
- IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height)
- {
- return SetStatus(DllExports::GdipDrawRectangle(nativeGraphics,
- pen->nativePen, x, y,
- width, height));
- }
-
- Status DrawRectangles(IN const Pen* pen,
- IN const RectF* rects,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawRectangles(nativeGraphics,
- pen->nativePen,
- rects, count));
- }
-
- // integer version
- Status DrawRectangle(IN const Pen* pen,
- IN const Rect& rect)
- {
- return DrawRectangle(pen,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height);
- }
-
- Status DrawRectangle(IN const Pen* pen,
- IN INT x,
- IN INT y,
- IN INT width,
- IN INT height)
- {
- return SetStatus(DllExports::GdipDrawRectangleI(nativeGraphics,
- pen->nativePen,
- x,
- y,
- width,
- height));
- }
-
- Status DrawRectangles(IN const Pen* pen,
- IN const Rect* rects,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawRectanglesI(nativeGraphics,
- pen->nativePen,
- rects,
- count));
- }
-
- // float version
- Status DrawEllipse(IN const Pen* pen,
- IN const RectF& rect)
- {
- return DrawEllipse(pen, rect.X, rect.Y, rect.Width, rect.Height);
- }
-
- Status DrawEllipse(IN const Pen* pen,
- IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height)
- {
- return SetStatus(DllExports::GdipDrawEllipse(nativeGraphics,
- pen->nativePen,
- x,
- y,
- width,
- height));
- }
-
- // integer version
- Status DrawEllipse(IN const Pen* pen,
- IN const Rect& rect)
- {
- return DrawEllipse(pen,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height);
- }
-
- Status DrawEllipse(IN const Pen* pen,
- IN INT x,
- IN INT y,
- IN INT width,
- IN INT height)
- {
- return SetStatus(DllExports::GdipDrawEllipseI(nativeGraphics,
- pen->nativePen,
- x,
- y,
- width,
- height));
- }
-
- // floating point version
- Status DrawPie(IN const Pen* pen,
- IN const RectF& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return DrawPie(pen,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height,
- startAngle,
- sweepAngle);
- }
-
- Status DrawPie(IN const Pen* pen,
- IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipDrawPie(nativeGraphics,
- pen->nativePen,
- x,
- y,
- width,
- height,
- startAngle,
- sweepAngle));
- }
-
- // integer point version
- Status DrawPie(IN const Pen* pen,
- IN const Rect& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return DrawPie(pen,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height,
- startAngle,
- sweepAngle);
- }
-
- Status DrawPie(IN const Pen* pen,
- IN INT x,
- IN INT y,
- IN INT width,
- IN INT height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipDrawPieI(nativeGraphics,
- pen->nativePen,
- x,
- y,
- width,
- height,
- startAngle,
- sweepAngle));
- }
-
- // float version
- Status DrawPolygon(IN const Pen* pen,
- IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawPolygon(nativeGraphics,
- pen->nativePen,
- points,
- count));
- }
-
- // integer version
- Status DrawPolygon(IN const Pen* pen,
- IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawPolygonI(nativeGraphics,
- pen->nativePen,
- points,
- count));
- }
-
- // float version
- Status DrawPath(IN const Pen* pen,
- IN const GraphicsPath* path)
- {
- return SetStatus(DllExports::GdipDrawPath(nativeGraphics,
- pen ? pen->nativePen : NULL,
- path ? path->nativePath : NULL));
- }
-
- // float version
- Status DrawCurve(IN const Pen* pen,
- IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawCurve(nativeGraphics,
- pen->nativePen, points,
- count));
- }
-
- Status DrawCurve(IN const Pen* pen,
- IN const PointF* points,
- IN INT count,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipDrawCurve2(nativeGraphics,
- pen->nativePen, points,
- count, tension));
- }
-
- Status DrawCurve(IN const Pen* pen,
- IN const PointF* points,
- IN INT count,
- IN INT offset,
- IN INT numberOfSegments,
- IN REAL tension = 0.5f)
- {
- return SetStatus(DllExports::GdipDrawCurve3(nativeGraphics,
- pen->nativePen, points,
- count, offset,
- numberOfSegments, tension));
- }
-
- // integer version
- Status DrawCurve(IN const Pen* pen,
- IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawCurveI(nativeGraphics,
- pen->nativePen,
- points,
- count));
- }
-
- Status DrawCurve(IN const Pen* pen,
- IN const Point* points,
- IN INT count,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipDrawCurve2I(nativeGraphics,
- pen->nativePen,
- points,
- count,
- tension));
- }
-
- Status DrawCurve(IN const Pen* pen,
- IN const Point* points,
- IN INT count,
- IN INT offset,
- IN INT numberOfSegments,
- IN REAL tension = 0.5f)
- {
- return SetStatus(DllExports::GdipDrawCurve3I(nativeGraphics,
- pen->nativePen,
- points,
- count,
- offset,
- numberOfSegments,
- tension));
- }
-
- // float version
- Status DrawClosedCurve(IN const Pen* pen,
- IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawClosedCurve(nativeGraphics,
- pen->nativePen,
- points, count));
- }
-
- Status DrawClosedCurve(IN const Pen *pen,
- IN const PointF* points,
- IN INT count,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipDrawClosedCurve2(nativeGraphics,
- pen->nativePen,
- points, count,
- tension));
- }
-
- // integer version
- Status DrawClosedCurve(IN const Pen* pen,
- IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipDrawClosedCurveI(nativeGraphics,
- pen->nativePen,
- points,
- count));
- }
-
- Status DrawClosedCurve(IN const Pen *pen,
- IN const Point* points,
- IN INT count,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipDrawClosedCurve2I(nativeGraphics,
- pen->nativePen,
- points,
- count,
- tension));
- }
-
- Status Clear(IN const Color &color)
- {
- return SetStatus(DllExports::GdipGraphicsClear(
- nativeGraphics,
- color.GetValue()));
- }
-
- // float version
- Status FillRectangle(IN const Brush* brush,
- IN const RectF& rect)
- {
- return FillRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height);
- }
-
- Status FillRectangle(IN const Brush* brush,
- IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height)
- {
- return SetStatus(DllExports::GdipFillRectangle(nativeGraphics,
- brush->nativeBrush, x, y,
- width, height));
- }
-
- Status FillRectangles(IN const Brush* brush,
- IN const RectF* rects,
- IN INT count)
- {
- return SetStatus(DllExports::GdipFillRectangles(nativeGraphics,
- brush->nativeBrush,
- rects, count));
- }
-
- // integer version
- Status FillRectangle(IN const Brush* brush,
- IN const Rect& rect)
- {
- return FillRectangle(brush,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height);
- }
-
- Status FillRectangle(IN const Brush* brush,
- IN INT x,
- IN INT y,
- IN INT width,
- IN INT height)
- {
- return SetStatus(DllExports::GdipFillRectangleI(nativeGraphics,
- brush->nativeBrush,
- x,
- y,
- width,
- height));
- }
-
- Status FillRectangles(IN const Brush* brush,
- IN const Rect* rects,
- IN INT count)
- {
- return SetStatus(DllExports::GdipFillRectanglesI(nativeGraphics,
- brush->nativeBrush,
- rects,
- count));
- }
-
- // float version
- Status FillPolygon(IN const Brush* brush,
- IN const PointF* points,
- IN INT count)
- {
- return FillPolygon(brush, points, count, FillModeAlternate);
- }
-
- Status FillPolygon(IN const Brush* brush,
- IN const PointF* points,
- IN INT count,
- IN FillMode fillMode)
- {
- return SetStatus(DllExports::GdipFillPolygon(nativeGraphics,
- brush->nativeBrush,
- points, count, fillMode));
- }
-
- // integer version
- Status FillPolygon(IN const Brush* brush,
- IN const Point* points,
- IN INT count)
- {
- return FillPolygon(brush, points, count, FillModeAlternate);
- }
-
- Status FillPolygon(IN const Brush* brush,
- IN const Point* points,
- IN INT count,
- IN FillMode fillMode)
- {
- return SetStatus(DllExports::GdipFillPolygonI(nativeGraphics,
- brush->nativeBrush,
- points, count,
- fillMode));
- }
-
- // float version
- Status FillEllipse(IN const Brush* brush,
- IN const RectF& rect)
- {
- return FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height);
- }
-
- Status FillEllipse(IN const Brush* brush,
- IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height)
- {
- return SetStatus(DllExports::GdipFillEllipse(nativeGraphics,
- brush->nativeBrush, x, y,
- width, height));
- }
-
- // integer version
- Status FillEllipse(IN const Brush* brush,
- IN const Rect& rect)
- {
- return FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height);
- }
-
- Status FillEllipse(IN const Brush* brush,
- IN INT x,
- IN INT y,
- IN INT width,
- IN INT height)
- {
- return SetStatus(DllExports::GdipFillEllipseI(nativeGraphics,
- brush->nativeBrush,
- x,
- y,
- width,
- height));
- }
-
- // float version
- Status FillPie(IN const Brush* brush,
- IN const RectF& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height,
- startAngle, sweepAngle);
- }
-
- Status FillPie(IN const Brush* brush,
- IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipFillPie(nativeGraphics,
- brush->nativeBrush, x, y,
- width, height, startAngle,
- sweepAngle));
- }
-
- // integer version
- Status FillPie(IN const Brush* brush,
- IN const Rect& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height,
- startAngle, sweepAngle);
- }
-
- Status FillPie(IN const Brush* brush,
- IN INT x,
- IN INT y,
- IN INT width,
- IN INT height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipFillPieI(nativeGraphics,
- brush->nativeBrush,
- x,
- y,
- width,
- height,
- startAngle,
- sweepAngle));
- }
-
- Status FillPath(IN const Brush* brush,
- IN const GraphicsPath* path)
- {
- return SetStatus(DllExports::GdipFillPath(nativeGraphics,
- brush->nativeBrush,
- path->nativePath));
- }
-
- // float version
- Status FillClosedCurve(IN const Brush* brush,
- IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipFillClosedCurve(nativeGraphics,
- brush->nativeBrush,
- points, count));
-
- }
-
- Status FillClosedCurve(IN const Brush* brush,
- IN const PointF* points,
- IN INT count,
- IN FillMode fillMode,
- IN REAL tension = 0.5f)
- {
- return SetStatus(DllExports::GdipFillClosedCurve2(nativeGraphics,
- brush->nativeBrush,
- points, count,
- tension, fillMode));
- }
-
- // integer version
- Status FillClosedCurve(IN const Brush* brush,
- IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipFillClosedCurveI(nativeGraphics,
- brush->nativeBrush,
- points,
- count));
- }
-
- Status FillClosedCurve(IN const Brush* brush,
- IN const Point* points,
- IN INT count,
- IN FillMode fillMode,
- IN REAL tension = 0.5f)
- {
- return SetStatus(DllExports::GdipFillClosedCurve2I(nativeGraphics,
- brush->nativeBrush,
- points, count,
- tension, fillMode));
- }
-
- // float version
- Status FillRegion(IN const Brush* brush,
- IN const Region* region)
- {
- return SetStatus(DllExports::GdipFillRegion(nativeGraphics,
- brush->nativeBrush,
- region->nativeRegion));
- }
-
- // DrawString and MeasureString
- Status
- DrawString(
- IN const WCHAR *string,
- IN INT length,
- IN const Font *font,
- IN const RectF &layoutRect,
- IN const StringFormat *stringFormat,
- IN const Brush *brush
- )
- {
- return SetStatus(DllExports::GdipDrawString(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- &layoutRect,
- stringFormat ? stringFormat->nativeFormat : NULL,
- brush ? brush->nativeBrush : NULL
- ));
- }
-
- Status
- DrawString(
- const WCHAR *string,
- INT length,
- const Font *font,
- const PointF &origin,
- const Brush *brush
- )
- {
- RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
-
- return SetStatus(DllExports::GdipDrawString(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- &rect,
- NULL,
- brush ? brush->nativeBrush : NULL
- ));
- }
-
- Status
- DrawString(
- const WCHAR *string,
- INT length,
- const Font *font,
- const PointF &origin,
- const StringFormat *stringFormat,
- const Brush *brush
- )
- {
- RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
-
- return SetStatus(DllExports::GdipDrawString(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- &rect,
- stringFormat ? stringFormat->nativeFormat : NULL,
- brush ? brush->nativeBrush : NULL
- ));
- }
-
- Status
- MeasureString(
- IN const WCHAR *string,
- IN INT length,
- IN const Font *font,
- IN const RectF &layoutRect,
- IN const StringFormat *stringFormat,
- OUT RectF *boundingBox,
- OUT INT *codepointsFitted = 0,
- OUT INT *linesFilled = 0
- ) const
- {
- return SetStatus(DllExports::GdipMeasureString(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- &layoutRect,
- stringFormat ? stringFormat->nativeFormat : NULL,
- boundingBox,
- codepointsFitted,
- linesFilled
- ));
- }
-
- Status
- MeasureString(
- IN const WCHAR *string,
- IN INT length,
- IN const Font *font,
- IN const SizeF &layoutRectSize,
- IN const StringFormat *stringFormat,
- OUT SizeF *size,
- OUT INT *codepointsFitted = 0,
- OUT INT *linesFilled = 0
- ) const
- {
- RectF layoutRect(0, 0, layoutRectSize.Width, layoutRectSize.Height);
- RectF boundingBox;
- Status status;
-
- if (size == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- status = SetStatus(DllExports::GdipMeasureString(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- &layoutRect,
- stringFormat ? stringFormat->nativeFormat : NULL,
- size ? &boundingBox : NULL,
- codepointsFitted,
- linesFilled
- ));
-
- if (size && status == Ok)
- {
- size->Width = boundingBox.Width;
- size->Height = boundingBox.Height;
- }
-
- return status;
- }
-
- Status
- MeasureString(
- IN const WCHAR *string,
- IN INT length,
- IN const Font *font,
- IN const PointF &origin,
- IN const StringFormat *stringFormat,
- OUT RectF *boundingBox
- ) const
- {
- RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
-
- return SetStatus(DllExports::GdipMeasureString(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- &rect,
- stringFormat ? stringFormat->nativeFormat : NULL,
- boundingBox,
- NULL,
- NULL
- ));
- }
-
-
- Status
- MeasureString(
- IN const WCHAR *string,
- IN INT length,
- IN const Font *font,
- IN const RectF &layoutRect,
- OUT RectF *boundingBox
- ) const
- {
- return SetStatus(DllExports::GdipMeasureString(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- &layoutRect,
- NULL,
- boundingBox,
- NULL,
- NULL
- ));
- }
-
- Status
- MeasureString(
- IN const WCHAR *string,
- IN INT length,
- IN const Font *font,
- IN const PointF &origin,
- OUT RectF *boundingBox
- ) const
- {
- RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
-
- return SetStatus(DllExports::GdipMeasureString(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- &rect,
- NULL,
- boundingBox,
- NULL,
- NULL
- ));
- }
-
-
-#ifdef DCR_USE_NEW_174340
- Status
- MeasureCharacterRanges(
- IN const WCHAR *string,
- IN INT length,
- IN const Font *font,
- IN const RectF &layoutRect,
- IN const StringFormat *stringFormat,
- IN INT regionCount,
- OUT Region *regions
- ) const
- {
- if (!regions || regionCount <= 0)
- {
- return InvalidParameter;
- }
-
- GpRegion **nativeRegions = new GpRegion* [regionCount];
-
- if (!nativeRegions)
- {
- return OutOfMemory;
- }
-
- for (INT i = 0; i < regionCount; i++)
- {
- nativeRegions[i] = regions[i].nativeRegion;
- }
-
- Status status = SetStatus(DllExports::GdipMeasureCharacterRanges(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- layoutRect,
- stringFormat ? stringFormat->nativeFormat : NULL,
- regionCount,
- nativeRegions
- ));
-
- delete [] nativeRegions;
-
- return status;
- }
-#endif
-
-
-#ifndef DCR_USE_NEW_174340
- Status
- MeasureStringRegion(
- IN const WCHAR *string,
- IN INT length,
- IN const Font *font,
- IN const RectF &layoutRect,
- IN const StringFormat *stringFormat,
- IN INT firstCharacterIndex,
- IN INT characterCount,
- OUT Region *region
- ) const
- {
- if (region == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- return (SetStatus(DllExports::GdipMeasureStringRegion(
- nativeGraphics,
- string,
- length,
- font ? font->nativeFont : NULL,
- layoutRect,
- stringFormat ? stringFormat->nativeFormat : NULL,
- firstCharacterIndex,
- characterCount,
- region->nativeRegion)));
- }
-#endif
-
- Status DrawDriverString(
- IN const UINT16 *text,
- IN INT length,
- IN const Font *font,
- IN const Brush *brush,
- IN const PointF *positions,
- IN INT flags,
- IN const Matrix *matrix
- )
- {
- return SetStatus(DllExports::GdipDrawDriverString(
- nativeGraphics,
- text,
- length,
- font ? font->nativeFont : NULL,
- brush ? brush->nativeBrush : NULL,
- positions,
- flags,
- matrix ? matrix->nativeMatrix : NULL
- ));
- }
-
- Status MeasureDriverString(
- IN const UINT16 *text,
- IN INT length,
- IN const Font *font,
- IN const PointF *positions,
- IN INT flags,
- IN const Matrix *matrix,
- OUT RectF *boundingBox
- ) const
- {
- return SetStatus(DllExports::GdipMeasureDriverString(
- nativeGraphics,
- text,
- length,
- font ? font->nativeFont : NULL,
- positions,
- flags,
- matrix ? matrix->nativeMatrix : NULL,
- boundingBox
- ));
- }
-
-#ifndef DCR_USE_NEW_168772
- Status DriverStringPointToCodepoint(
- IN const UINT16 *text,
- IN INT length,
- IN const Font *font,
- IN const PointF *positions,
- IN INT flags,
- IN const Matrix *matrix,
- IN const PointF &hit,
- OUT INT *index,
- OUT BOOL *rightEdge,
- OUT REAL *distance
- )
- {
- return SetStatus(DllExports::GdipDriverStringPointToCodepoint(
- nativeGraphics,
- text,
- length,
- font ? font->nativeFont : NULL,
- positions,
- flags,
- matrix ? matrix->nativeMatrix : NULL,
- &hit,
- index,
- rightEdge,
- distance
- ));
- }
-#endif
-
- // Draw a cached bitmap on this graphics destination offset by
- // x, y. Note this will fail with WrongState if the CachedBitmap
- // native format differs from this Graphics.
-
- Status DrawCachedBitmap(IN CachedBitmap *cb,
- IN INT x,
- IN INT y)
- {
- return SetStatus(DllExports::GdipDrawCachedBitmap(
- nativeGraphics,
- cb->nativeCachedBitmap,
- x, y
- ));
- }
-
- /**
- * Draw images (both bitmap and vector)
- */
- // float version
- Status DrawImage(IN Image* image,
- IN const PointF& point)
- {
- return DrawImage(image, point.X, point.Y);
- }
-
- Status DrawImage(IN Image* image,
- IN REAL x,
- IN REAL y)
- {
- return SetStatus(DllExports::GdipDrawImage(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- x,
- y));
- }
-
- Status DrawImage(IN Image* image,
- IN const RectF& rect)
- {
- return DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);
- }
-
- Status DrawImage(IN Image* image,
- IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height)
- {
- return SetStatus(DllExports::GdipDrawImageRect(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- x,
- y,
- width,
- height));
- }
-
- // integer version
- Status DrawImage(IN Image* image,
- IN const Point& point)
- {
- return DrawImage(image, point.X, point.Y);
- }
-
- Status DrawImage(IN Image* image,
- IN INT x,
- IN INT y)
- {
- return SetStatus(DllExports::GdipDrawImageI(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- x,
- y));
- }
-
- Status DrawImage(IN Image* image,
- IN const Rect& rect)
- {
- return DrawImage(image,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height);
- }
-
- Status DrawImage(IN Image* image,
- IN INT x,
- IN INT y,
- IN INT width,
- IN INT height) {
- return SetStatus(DllExports::GdipDrawImageRectI(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- x,
- y,
- width,
- height));
- }
-
- /**
- * Affine or perspective blt
- * destPoints.length = 3: rect => parallelogram
- * destPoints[0] <=> top-left corner of the source rectangle
- * destPoints[1] <=> top-right corner
- * destPoints[2] <=> bottom-left corner
- * destPoints.length = 4: rect => quad
- * destPoints[3] <=> bottom-right corner
- *
- * @notes Perspective blt only works for bitmap images.
- */
- Status DrawImage(IN Image* image,
- IN const PointF* destPoints,
- IN INT count)
- {
- if (count != 3 && count != 4)
- return SetStatus(InvalidParameter);
-
- return SetStatus(DllExports::GdipDrawImagePoints(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- destPoints, count));
- }
-
- Status DrawImage(IN Image* image,
- IN const Point* destPoints,
- IN INT count)
- {
- if (count != 3 && count != 4)
- return SetStatus(InvalidParameter);
-
- return SetStatus(DllExports::GdipDrawImagePointsI(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- destPoints,
- count));
- }
-
- /**
- * We need another set of methods similar to the ones above
- * that take an additional Rect parameter to specify the
- * portion of the source image to be drawn.
- */
- // float version
- Status DrawImage(IN Image* image,
- IN REAL x,
- IN REAL y,
- IN REAL srcx,
- IN REAL srcy,
- IN REAL srcwidth,
- IN REAL srcheight,
- IN Unit srcUnit)
- {
- return SetStatus(DllExports::GdipDrawImagePointRect(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- x, y,
- srcx, srcy,
- srcwidth, srcheight, srcUnit));
- }
-
- Status DrawImage(IN Image* image,
- IN const RectF& destRect,
- IN REAL srcx,
- IN REAL srcy,
- IN REAL srcwidth,
- IN REAL srcheight,
- IN Unit srcUnit,
- IN const ImageAttributes* imageAttributes = NULL,
- IN DrawImageAbort callback = NULL,
- IN VOID* callbackData = NULL)
- {
- return SetStatus(DllExports::GdipDrawImageRectRect(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- destRect.X,
- destRect.Y,
- destRect.Width,
- destRect.Height,
- srcx, srcy,
- srcwidth, srcheight,
- srcUnit,
- imageAttributes
- ? imageAttributes->nativeImageAttr
- : NULL,
- callback,
- callbackData));
- }
-
- Status DrawImage(IN Image* image,
- IN const PointF* destPoints,
- IN INT count,
- IN REAL srcx,
- IN REAL srcy,
- IN REAL srcwidth,
- IN REAL srcheight,
- IN Unit srcUnit,
- IN const ImageAttributes* imageAttributes = NULL,
- IN DrawImageAbort callback = NULL,
- IN VOID* callbackData = NULL)
- {
- return SetStatus(DllExports::GdipDrawImagePointsRect(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- destPoints, count,
- srcx, srcy,
- srcwidth,
- srcheight,
- srcUnit,
- imageAttributes
- ? imageAttributes->nativeImageAttr
- : NULL,
- callback,
- callbackData));
- }
-
- // integer version
- Status DrawImage(IN Image* image,
- IN INT x,
- IN INT y,
- IN INT srcx,
- IN INT srcy,
- IN INT srcwidth,
- IN INT srcheight,
- IN Unit srcUnit)
- {
- return SetStatus(DllExports::GdipDrawImagePointRectI(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- x,
- y,
- srcx,
- srcy,
- srcwidth,
- srcheight,
- srcUnit));
- }
-
- Status DrawImage(IN Image* image,
- IN const Rect& destRect,
- IN INT srcx,
- IN INT srcy,
- IN INT srcwidth,
- IN INT srcheight,
- IN Unit srcUnit,
- IN const ImageAttributes* imageAttributes = NULL,
- IN DrawImageAbort callback = NULL,
- IN VOID* callbackData = NULL)
- {
- return SetStatus(DllExports::GdipDrawImageRectRectI(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- destRect.X,
- destRect.Y,
- destRect.Width,
- destRect.Height,
- srcx,
- srcy,
- srcwidth,
- srcheight,
- srcUnit,
- imageAttributes
- ? imageAttributes->nativeImageAttr
- : NULL,
- callback,
- callbackData));
- }
-
- Status DrawImage(IN Image* image,
- IN const Point* destPoints,
- IN INT count,
- IN INT srcx,
- IN INT srcy,
- IN INT srcwidth,
- IN INT srcheight,
- IN Unit srcUnit,
- IN const ImageAttributes* imageAttributes = NULL,
- IN DrawImageAbort callback = NULL,
- IN VOID* callbackData = NULL)
- {
- return SetStatus(DllExports::GdipDrawImagePointsRectI(nativeGraphics,
- image ? image->nativeImage
- : NULL,
- destPoints,
- count,
- srcx,
- srcy,
- srcwidth,
- srcheight,
- srcUnit,
- imageAttributes
- ? imageAttributes->nativeImageAttr
- : NULL,
- callback,
- callbackData));
- }
-
- // The following methods are for playing an EMF+ to a graphics
- // via the enumeration interface. Each record of the EMF+ is
- // sent to the callback (along with the callbackData). Then
- // the callback can invoke the Metafile::PlayRecord method
- // to play the particular record.
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const PointF & destPoint,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileDestPoint(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destPoint,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const Point & destPoint,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileDestPointI(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destPoint,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const RectF & destRect,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileDestRect(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destRect,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const Rect & destRect,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileDestRectI(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destRect,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const PointF * destPoints,
- IN INT count,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileDestPoints(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destPoints,
- count,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const Point * destPoints,
- IN INT count,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileDestPointsI(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destPoints,
- count,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const PointF & destPoint,
- IN const RectF & srcRect,
- IN Unit srcUnit,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPoint(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destPoint,
- srcRect,
- srcUnit,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const Point & destPoint,
- IN const Rect & srcRect,
- IN Unit srcUnit,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPointI(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destPoint,
- srcRect,
- srcUnit,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const RectF & destRect,
- IN const RectF & srcRect,
- IN Unit srcUnit,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestRect(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destRect,
- srcRect,
- srcUnit,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const Rect & destRect,
- IN const Rect & srcRect,
- IN Unit srcUnit,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestRectI(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destRect,
- srcRect,
- srcUnit,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const PointF * destPoints,
- IN INT count,
- IN const RectF & srcRect,
- IN Unit srcUnit,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPoints(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destPoints,
- count,
- srcRect,
- srcUnit,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- Status
- EnumerateMetafile(
- IN const Metafile * metafile,
- IN const Point * destPoints,
- IN INT count,
- IN const Rect & srcRect,
- IN Unit srcUnit,
- IN EnumerateMetafileProc callback,
- IN VOID * callbackData = NULL,
- IN const ImageAttributes * imageAttributes = NULL
- )
- {
- return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPointsI(
- nativeGraphics,
- (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
- destPoints,
- count,
- srcRect,
- srcUnit,
- callback,
- callbackData,
- imageAttributes ? imageAttributes->nativeImageAttr : NULL));
- }
-
- /**
- * Clipping region operations
- *
- * @notes Simply incredible redundancy here.
- */
- Status SetClip(IN const Graphics* g,
- IN CombineMode combineMode = CombineModeReplace)
- {
- return SetStatus(DllExports::GdipSetClipGraphics(nativeGraphics,
- g->nativeGraphics,
- combineMode));
- }
-
- Status SetClip(IN const RectF& rect,
- IN CombineMode combineMode = CombineModeReplace)
- {
- return SetStatus(DllExports::GdipSetClipRect(nativeGraphics,
- rect.X, rect.Y,
- rect.Width, rect.Height,
- combineMode));
- }
-
- Status SetClip(IN const Rect& rect,
- IN CombineMode combineMode = CombineModeReplace)
- {
- return SetStatus(DllExports::GdipSetClipRectI(nativeGraphics,
- rect.X, rect.Y,
- rect.Width, rect.Height,
- combineMode));
- }
-
- Status SetClip(IN const GraphicsPath* path,
- IN CombineMode combineMode = CombineModeReplace)
- {
- return SetStatus(DllExports::GdipSetClipPath(nativeGraphics,
- path->nativePath,
- combineMode));
- }
-
- Status SetClip(IN const Region* region,
- IN CombineMode combineMode = CombineModeReplace)
- {
- return SetStatus(DllExports::GdipSetClipRegion(nativeGraphics,
- region->nativeRegion,
- combineMode));
- }
-
- // This is different than the other SetClip methods because it assumes
- // that the HRGN is already in device units, so it doesn't transform
- // the coordinates in the HRGN.
- Status SetClip(IN HRGN hRgn,
- IN CombineMode combineMode = CombineModeReplace)
- {
- return SetStatus(DllExports::GdipSetClipHrgn(nativeGraphics, hRgn,
- combineMode));
- }
-
- Status IntersectClip(IN const RectF& rect)
- {
- return SetStatus(DllExports::GdipSetClipRect(nativeGraphics,
- rect.X, rect.Y,
- rect.Width, rect.Height,
- CombineModeIntersect));
- }
-
- Status IntersectClip(IN const Rect& rect)
- {
- return SetStatus(DllExports::GdipSetClipRectI(nativeGraphics,
- rect.X, rect.Y,
- rect.Width, rect.Height,
- CombineModeIntersect));
- }
-
- Status IntersectClip(IN const Region* region)
- {
- return SetStatus(DllExports::GdipSetClipRegion(nativeGraphics,
- region->nativeRegion,
- CombineModeIntersect));
- }
-
- Status ExcludeClip(IN const RectF& rect)
- {
- return SetStatus(DllExports::GdipSetClipRect(nativeGraphics,
- rect.X, rect.Y,
- rect.Width, rect.Height,
- CombineModeExclude));
- }
-
- Status ExcludeClip(IN const Rect& rect)
- {
- return SetStatus(DllExports::GdipSetClipRectI(nativeGraphics,
- rect.X, rect.Y,
- rect.Width, rect.Height,
- CombineModeExclude));
- }
-
- Status ExcludeClip(IN const Region* region)
- {
- return SetStatus(DllExports::GdipSetClipRegion(nativeGraphics,
- region->nativeRegion,
- CombineModeExclude));
- }
-
- Status ResetClip()
- {
- return SetStatus(DllExports::GdipResetClip(nativeGraphics));
- }
-
- Status TranslateClip(IN REAL dx,
- IN REAL dy)
- {
- return SetStatus(DllExports::GdipTranslateClip(nativeGraphics, dx, dy));
- }
-
- Status TranslateClip(IN INT dx,
- IN INT dy)
- {
- return SetStatus(DllExports::GdipTranslateClipI(nativeGraphics,
- dx, dy));
- }
-
- /**
- * GetClip region from graphics context
- */
- Status GetClip(OUT Region* region) const
- {
- return SetStatus(DllExports::GdipGetClip(nativeGraphics,
- region->nativeRegion));
- }
-
- /**
- * Hit testing operations
- */
- Status GetClipBounds(OUT RectF* rect) const
- {
- return SetStatus(DllExports::GdipGetClipBounds(nativeGraphics, rect));
- }
-
- Status GetClipBounds(OUT Rect* rect) const
- {
- return SetStatus(DllExports::GdipGetClipBoundsI(nativeGraphics, rect));
- }
-
- BOOL IsClipEmpty() const
- {
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsClipEmpty(nativeGraphics, &booln));
-
- return booln;
- }
-
- Status GetVisibleClipBounds(OUT RectF *rect) const
- {
-
- return SetStatus(DllExports::GdipGetVisibleClipBounds(nativeGraphics,
- rect));
- }
-
- Status GetVisibleClipBounds(OUT Rect *rect) const
- {
- return SetStatus(DllExports::GdipGetVisibleClipBoundsI(nativeGraphics,
- rect));
- }
-
- BOOL IsVisibleClipEmpty() const
- {
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsVisibleClipEmpty(nativeGraphics, &booln));
-
- return booln;
- }
-
- BOOL IsVisible(IN INT x,
- IN INT y) const
- {
- return IsVisible(Point(x,y));
- }
-
- BOOL IsVisible(IN const Point& point) const
- {
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsVisiblePointI(nativeGraphics,
- point.X,
- point.Y,
- &booln));
-
- return booln;
- }
-
- BOOL IsVisible(IN INT x,
- IN INT y,
- IN INT width,
- IN INT height) const
- {
- return IsVisible(Rect(x, y, width, height));
- }
-
- BOOL IsVisible(IN const Rect& rect) const
- {
-
- BOOL booln = TRUE;
-
- SetStatus(DllExports::GdipIsVisibleRectI(nativeGraphics,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height,
- &booln));
- return booln;
- }
-
- BOOL IsVisible(IN REAL x,
- IN REAL y) const
- {
- return IsVisible(PointF(x, y));
- }
-
- BOOL IsVisible(IN const PointF& point) const
- {
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsVisiblePoint(nativeGraphics,
- point.X,
- point.Y,
- &booln));
-
- return booln;
- }
-
- BOOL IsVisible(IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height) const
- {
- return IsVisible(RectF(x, y, width, height));
- }
-
- BOOL IsVisible(IN const RectF& rect) const
- {
- BOOL booln = TRUE;
-
- SetStatus(DllExports::GdipIsVisibleRect(nativeGraphics,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height,
- &booln));
- return booln;
- }
-
- /**
- * Save/restore graphics state
- */
- GraphicsState Save() const
- {
- GraphicsState gstate;
-
- SetStatus(DllExports::GdipSaveGraphics(nativeGraphics, &gstate));
-
- return gstate;
- }
-
- Status Restore(IN GraphicsState gstate)
- {
- return SetStatus(DllExports::GdipRestoreGraphics(nativeGraphics,
- gstate));
- }
-
- /**
- * Begin and end container drawing
- */
- GraphicsContainer BeginContainer(IN const RectF &dstrect,
- IN const RectF &srcrect,
- IN Unit unit)
- {
- GraphicsContainer state;
-
- SetStatus(DllExports::GdipBeginContainer(nativeGraphics, &dstrect,
- &srcrect, unit, &state));
-
- return state;
- }
-
- /**
- * Begin and end container drawing
- */
- GraphicsContainer BeginContainer(IN const Rect &dstrect,
- IN const Rect &srcrect,
- IN Unit unit)
- {
- GraphicsContainer state;
-
- SetStatus(DllExports::GdipBeginContainerI(nativeGraphics, &dstrect,
- &srcrect, unit, &state));
-
- return state;
- }
-
- GraphicsContainer BeginContainer()
- {
- GraphicsContainer state;
-
- SetStatus(DllExports::GdipBeginContainer2(nativeGraphics, &state));
-
- return state;
- }
-
- Status EndContainer(IN GraphicsContainer state)
- {
- return SetStatus(DllExports::GdipEndContainer(nativeGraphics, state));
- }
-
- // only valid when recording metafiles
- Status AddMetafileComment(IN const BYTE * data,
- IN UINT sizeData)
- {
- return SetStatus(DllExports::GdipComment(nativeGraphics, sizeData, data));
- }
-
- /**
- * Get/SetLayout
- * Support for Middle East localization (right-to-left mirroring)
- */
- GraphicsLayout GetLayout() const
- {
- GraphicsLayout layout;
-
- SetStatus(DllExports::GdipGetGraphicsLayout(nativeGraphics, &layout));
-
- return layout;
- }
-
- Status SetLayout(IN const GraphicsLayout layout)
- {
- return SetStatus(
- DllExports::GdipSetGraphicsLayout(nativeGraphics, layout)
- );
- }
-
- static HPALETTE GetHalftonePalette()
- {
- return DllExports::GdipCreateHalftonePalette();
- }
-
- Status GetLastStatus() const
- {
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
- }
-
-protected:
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- Graphics(const Graphics &);
- Graphics& operator=(const Graphics &);
-protected:
-
-#else
-
- Graphics(const Graphics& graphics)
- {
- graphics;
- SetStatus(NotImplemented);
- }
-
- Graphics& operator=(const Graphics& graphics)
- {
- graphics;
- SetStatus(NotImplemented);
- return *this;
- }
-
-#endif
-
- Graphics(GpGraphics* graphics)
- {
- lastResult = Ok;
- SetNativeGraphics(graphics);
- }
-
- VOID SetNativeGraphics(GpGraphics *graphics)
- {
- this->nativeGraphics = graphics;
- }
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
- // Methods necessary to subclass Graphics for extension test.
-
- GpGraphics* GetNativeGraphics() const
- {
- return this->nativeGraphics;
- }
-
- GpPen* GetNativePen(const Pen* pen)
- {
- return pen->nativePen;
- }
-
-protected:
- GpGraphics* nativeGraphics;
- mutable Status lastResult;
-
-};
-
-//----------------------------------------------------------------------------
-// Extra implementation of GraphicsPath methods that use Graphics
-//----------------------------------------------------------------------------
-
-/**
- * Get the bounds of the path object with the given transform.
- * This is not always the tightest bounds.
- */
-
-inline Status
-GraphicsPath::GetBounds(
- OUT RectF* bounds,
- IN const Matrix* matrix,
- IN const Pen* pen) const
-{
- GpMatrix* nativeMatrix = NULL;
- GpPen* nativePen = NULL;
-
- if (matrix)
- nativeMatrix = matrix->nativeMatrix;
-
- if (pen)
- nativePen = pen->nativePen;
-
- return SetStatus(DllExports::GdipGetPathWorldBounds(nativePath, bounds,
- nativeMatrix, nativePen));
-}
-
-// integer version
-inline Status
-GraphicsPath::GetBounds(
- OUT Rect* bounds,
- IN const Matrix* matrix,
- IN const Pen* pen
-) const
-{
- GpMatrix* nativeMatrix = NULL;
- GpPen* nativePen = NULL;
-
- if (matrix)
- nativeMatrix = matrix->nativeMatrix;
-
- if (pen)
- nativePen = pen->nativePen;
-
- return SetStatus(DllExports::GdipGetPathWorldBoundsI(nativePath, bounds,
- nativeMatrix, nativePen));
-}
-
-//----------------------------------------------------------------------------
-// Hit testing operations
-//----------------------------------------------------------------------------
-
-inline BOOL
-GraphicsPath::IsVisible(
- IN REAL x,
- IN REAL y,
- IN const Graphics* g) const
-{
- BOOL booln = FALSE;
-
- GpGraphics* nativeGraphics = NULL;
-
- if (g)
- nativeGraphics = g->nativeGraphics;
-
- SetStatus(DllExports::GdipIsVisiblePathPoint(nativePath,
- x, y, nativeGraphics,
- &booln));
- return booln;
-}
-
-inline BOOL
-GraphicsPath::IsVisible(
- IN INT x,
- IN INT y,
- IN const Graphics* g) const
-{
- BOOL booln = FALSE;
-
- GpGraphics* nativeGraphics = NULL;
-
- if (g)
- nativeGraphics = g->nativeGraphics;
-
- SetStatus(DllExports::GdipIsVisiblePathPointI(nativePath,
- x, y, nativeGraphics,
- &booln));
- return booln;
-}
-
-inline BOOL
-GraphicsPath::IsOutlineVisible(
- IN REAL x,
- IN REAL y,
- IN const Pen* pen,
- IN const Graphics* g) const
-{
- BOOL booln = FALSE;
-
- GpGraphics* nativeGraphics = NULL;
- GpPen* nativePen = NULL;
-
- if(g)
- nativeGraphics = g->nativeGraphics;
- if(pen)
- nativePen = pen->nativePen;
-
- SetStatus(DllExports::GdipIsOutlineVisiblePathPoint(nativePath,
- x, y, nativePen, nativeGraphics,
- &booln));
- return booln;
-}
-
-inline BOOL
-GraphicsPath::IsOutlineVisible(
- IN INT x,
- IN INT y,
- IN const Pen* pen,
- IN const Graphics* g) const
-{
- BOOL booln = FALSE;
-
- GpGraphics* nativeGraphics = NULL;
- GpPen* nativePen = NULL;
-
- if(g)
- nativeGraphics = g->nativeGraphics;
- if(pen)
- nativePen = pen->nativePen;
-
- SetStatus(DllExports::GdipIsOutlineVisiblePathPointI(nativePath,
- x, y, nativePen, nativeGraphics,
- &booln));
- return booln;
-}
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusGraphics.h
+*
+* Abstract:
+*
+* Declarations for Graphics class
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSGRAPHICS_H
+#define _GDIPLUSGRAPHICS_H
+
+/**
+ * Represent a graphics context
+ */
+class Graphics : public GdiplusBase
+{
+public:
+ friend class Region;
+ friend class GraphicsPath;
+ friend class Image;
+ friend class Bitmap;
+ friend class Metafile;
+ friend class Font;
+ friend class FontFamily;
+ friend class FontCollection;
+ friend class CachedBitmap;
+
+ // Get a graphics context from an existing Win32 HDC or HWND
+ static Graphics* FromHDC(IN HDC hdc)
+ {
+ return new Graphics(hdc);
+ }
+
+ static Graphics* FromHDC(IN HDC hdc,
+ IN HANDLE hdevice)
+ {
+ return new Graphics(hdc, hdevice);
+ }
+
+ static Graphics* FromHWND(IN HWND hwnd,
+ IN BOOL icm = FALSE)
+ {
+ return new Graphics(hwnd, icm);
+ }
+
+ static Graphics* FromImage(IN Image *image)
+ {
+ return new Graphics(image);
+ }
+
+ Graphics(IN HDC hdc)
+ {
+ GpGraphics *graphics = NULL;
+
+ lastResult = DllExports::GdipCreateFromHDC(hdc, &graphics);
+
+ SetNativeGraphics(graphics);
+ }
+
+ Graphics(IN HDC hdc,
+ IN HANDLE hdevice)
+ {
+ GpGraphics *graphics = NULL;
+
+ lastResult = DllExports::GdipCreateFromHDC2(hdc, hdevice, &graphics);
+
+ SetNativeGraphics(graphics);
+ }
+
+ Graphics(IN HWND hwnd,
+ IN BOOL icm = FALSE)
+ {
+ GpGraphics *graphics = NULL;
+
+ if (icm)
+ {
+ lastResult = DllExports::GdipCreateFromHWNDICM(hwnd, &graphics);
+ }
+ else
+ {
+ lastResult = DllExports::GdipCreateFromHWND(hwnd, &graphics);
+ }
+
+ SetNativeGraphics(graphics);
+ }
+
+ Graphics(IN Image* image)
+ {
+ GpGraphics *graphics = NULL;
+
+ if (image != NULL)
+ {
+ lastResult = DllExports::GdipGetImageGraphicsContext(
+ image->nativeImage, &graphics);
+ }
+ SetNativeGraphics(graphics);
+ }
+
+ ~Graphics()
+ {
+ DllExports::GdipDeleteGraphics(nativeGraphics);
+ }
+
+ VOID Flush(IN FlushIntention intention = FlushIntentionFlush)
+ {
+ DllExports::GdipFlush(nativeGraphics, intention);
+ }
+
+ //------------------------------------------------------------------------
+ // Interop methods
+ //------------------------------------------------------------------------
+
+ // Locks the graphics until ReleaseDC is called
+ HDC GetHDC()
+ {
+ HDC hdc = NULL;
+
+ SetStatus(DllExports::GdipGetDC(nativeGraphics, &hdc));
+
+ return hdc;
+ }
+
+ VOID ReleaseHDC(IN HDC hdc)
+ {
+ SetStatus(DllExports::GdipReleaseDC(nativeGraphics, hdc));
+ }
+
+ //------------------------------------------------------------------------
+ // Rendering modes
+ //------------------------------------------------------------------------
+
+ Status SetRenderingOrigin(IN INT x, IN INT y)
+ {
+ return SetStatus(
+ DllExports::GdipSetRenderingOrigin(
+ nativeGraphics, x, y
+ )
+ );
+ }
+
+ Status GetRenderingOrigin(OUT INT *x, OUT INT *y) const
+ {
+ return SetStatus(
+ DllExports::GdipGetRenderingOrigin(
+ nativeGraphics, x, y
+ )
+ );
+ }
+
+ Status SetCompositingMode(IN CompositingMode compositingMode)
+ {
+ return SetStatus(DllExports::GdipSetCompositingMode(nativeGraphics,
+ compositingMode));
+ }
+
+ CompositingMode GetCompositingMode() const
+ {
+ CompositingMode mode;
+
+ SetStatus(DllExports::GdipGetCompositingMode(nativeGraphics,
+ &mode));
+
+ return mode;
+ }
+
+ Status SetCompositingQuality(IN CompositingQuality compositingQuality)
+ {
+ return SetStatus(DllExports::GdipSetCompositingQuality(
+ nativeGraphics,
+ compositingQuality));
+ }
+
+ CompositingQuality GetCompositingQuality() const
+ {
+ CompositingQuality quality;
+
+ SetStatus(DllExports::GdipGetCompositingQuality(
+ nativeGraphics,
+ &quality));
+
+ return quality;
+ }
+
+ Status SetTextRenderingHint(IN TextRenderingHint newMode)
+ {
+#ifndef DCR_USE_NEW_186764
+ /* temporarly set the high bit to warn that we are using the new definition for the flag */
+ newMode = (TextRenderingHint) (newMode | 0x0f000);
+#endif // DCR_USE_NEW_186764
+ return SetStatus(DllExports::GdipSetTextRenderingHint(nativeGraphics,
+ newMode));
+ }
+
+ TextRenderingHint GetTextRenderingHint() const
+ {
+ TextRenderingHint hint;
+
+ SetStatus(DllExports::GdipGetTextRenderingHint(nativeGraphics,
+ &hint));
+
+ return hint;
+ }
+
+#ifdef DCR_USE_NEW_188922
+ Status SetTextContrast(IN UINT contrast)
+ {
+ return SetStatus(DllExports::GdipSetTextContrast(nativeGraphics,
+ contrast));
+ }
+
+ UINT GetTextContrast() const
+ {
+ UINT contrast;
+
+ SetStatus(DllExports::GdipGetTextContrast(nativeGraphics,
+ &contrast));
+
+ return contrast;
+ }
+#else
+ Status SetTextGammaValue(IN UINT gammaValue)
+ {
+ return SetStatus(DllExports::GdipSetTextGammaValue(nativeGraphics,
+ gammaValue));
+ }
+
+ UINT GetTextGammaValue() const
+ {
+ UINT gammaValue;
+
+ SetStatus(DllExports::GdipGetTextGammaValue(nativeGraphics,
+ &gammaValue));
+
+ return gammaValue;
+ }
+
+#endif // DCR_USE_NEW_188922
+
+
+ InterpolationMode GetInterpolationMode() const
+ {
+ InterpolationMode mode = InterpolationModeInvalid;
+
+ SetStatus(DllExports::GdipGetInterpolationMode(nativeGraphics,
+ &mode));
+
+ return mode;
+ }
+
+ Status SetInterpolationMode(IN InterpolationMode interpolationMode)
+ {
+ return SetStatus(DllExports::GdipSetInterpolationMode(nativeGraphics,
+ interpolationMode));
+ }
+
+ SmoothingMode GetSmoothingMode() const
+ {
+ SmoothingMode smoothingMode = SmoothingModeInvalid;
+
+ SetStatus(DllExports::GdipGetSmoothingMode(nativeGraphics,
+ &smoothingMode));
+
+ return smoothingMode;
+ }
+
+ Status SetSmoothingMode(IN SmoothingMode smoothingMode)
+ {
+ return SetStatus(DllExports::GdipSetSmoothingMode(nativeGraphics,
+ smoothingMode));
+ }
+
+ PixelOffsetMode GetPixelOffsetMode() const
+ {
+ PixelOffsetMode pixelOffsetMode = PixelOffsetModeInvalid;
+
+ SetStatus(DllExports::GdipGetPixelOffsetMode(nativeGraphics,
+ &pixelOffsetMode));
+
+ return pixelOffsetMode;
+ }
+
+ Status SetPixelOffsetMode(IN PixelOffsetMode pixelOffsetMode)
+ {
+ return SetStatus(DllExports::GdipSetPixelOffsetMode(nativeGraphics,
+ pixelOffsetMode));
+ }
+
+ //------------------------------------------------------------------------
+ // Manipulate the current world transform
+ //------------------------------------------------------------------------
+
+ Status SetTransform(IN const Matrix* matrix)
+ {
+ return SetStatus(DllExports::GdipSetWorldTransform(nativeGraphics,
+ matrix->nativeMatrix));
+ }
+ Status ResetTransform()
+ {
+ return SetStatus(DllExports::GdipResetWorldTransform(nativeGraphics));
+ }
+
+ Status MultiplyTransform(IN const Matrix* matrix,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipMultiplyWorldTransform(nativeGraphics,
+ matrix->nativeMatrix,
+ order));
+ }
+
+ Status TranslateTransform(IN REAL dx,
+ IN REAL dy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipTranslateWorldTransform(nativeGraphics,
+ dx, dy, order));
+ }
+
+ Status ScaleTransform(IN REAL sx,
+ IN REAL sy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipScaleWorldTransform(nativeGraphics,
+ sx, sy, order));
+ }
+
+ Status RotateTransform(IN REAL angle,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipRotateWorldTransform(nativeGraphics,
+ angle, order));
+ }
+
+ /**
+ * Return the current world transform
+ */
+
+ Status GetTransform(OUT Matrix* matrix) const
+ {
+ return SetStatus(DllExports::GdipGetWorldTransform(nativeGraphics,
+ matrix->nativeMatrix));
+ }
+
+ /**
+ * Manipulate the current page transform
+ */
+
+ Status SetPageUnit(IN Unit unit)
+ {
+ return SetStatus(DllExports::GdipSetPageUnit(nativeGraphics,
+ unit));
+ }
+
+ Status SetPageScale(IN REAL scale)
+ {
+ return SetStatus(DllExports::GdipSetPageScale(nativeGraphics,
+ scale));
+ }
+
+ /**
+ * Retrieve the current page transform information
+ * notes @ these are atomic
+ */
+ Unit GetPageUnit() const
+ {
+ Unit unit;
+
+ SetStatus(DllExports::GdipGetPageUnit(nativeGraphics, &unit));
+
+ return unit;
+ }
+
+ REAL GetPageScale() const
+ {
+ REAL scale;
+
+ SetStatus(DllExports::GdipGetPageScale(nativeGraphics, &scale));
+
+ return scale;
+ }
+
+ REAL GetDpiX() const
+ {
+ REAL dpi;
+
+ SetStatus(DllExports::GdipGetDpiX(nativeGraphics, &dpi));
+
+ return dpi;
+ }
+
+ REAL GetDpiY() const
+ {
+ REAL dpi;
+
+ SetStatus(DllExports::GdipGetDpiY(nativeGraphics, &dpi));
+
+ return dpi;
+ }
+
+ /**
+ * Transform points in the current graphics context
+ */
+ // float version
+ Status TransformPoints(IN CoordinateSpace destSpace,
+ IN CoordinateSpace srcSpace,
+ IN OUT PointF* pts,
+ IN INT count) const
+ {
+ return SetStatus(DllExports::GdipTransformPoints(nativeGraphics,
+ destSpace,
+ srcSpace,
+ pts,
+ count));
+ }
+
+ // integer version
+ Status TransformPoints(IN CoordinateSpace destSpace,
+ IN CoordinateSpace srcSpace,
+ IN OUT Point* pts,
+ IN INT count) const
+ {
+
+ return SetStatus(DllExports::GdipTransformPointsI(nativeGraphics,
+ destSpace,
+ srcSpace,
+ pts,
+ count));
+ }
+
+ //------------------------------------------------------------------------
+ // GetNearestColor (for <= 8bpp surfaces)
+ // Note: alpha is ignored
+ //------------------------------------------------------------------------
+ Status GetNearestColor(IN OUT Color* color) const
+ {
+ if (color == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ ARGB argb = color->GetValue();
+
+ Status status = SetStatus(DllExports::GdipGetNearestColor(nativeGraphics, &argb));
+
+ color->SetValue(argb);
+
+ return status;
+ }
+
+ /**
+ * Vector drawing methods
+ *
+ * @notes Do we need a set of methods that take
+ * integer coordinate parameters?
+ */
+
+ // float version
+ Status DrawLine(IN const Pen* pen,
+ IN REAL x1,
+ IN REAL y1,
+ IN REAL x2,
+ IN REAL y2)
+ {
+ return SetStatus(DllExports::GdipDrawLine(nativeGraphics,
+ pen->nativePen, x1, y1, x2,
+ y2));
+ }
+
+ Status DrawLine(IN const Pen* pen,
+ IN const PointF& pt1,
+ IN const PointF& pt2)
+ {
+ return DrawLine(pen, pt1.X, pt1.Y, pt2.X, pt2.Y);
+ }
+
+ Status DrawLines(IN const Pen* pen,
+ IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawLines(nativeGraphics,
+ pen->nativePen,
+ points, count));
+ }
+
+ // int version
+ Status DrawLine(IN const Pen* pen,
+ IN INT x1,
+ IN INT y1,
+ IN INT x2,
+ IN INT y2)
+ {
+ return SetStatus(DllExports::GdipDrawLineI(nativeGraphics,
+ pen->nativePen,
+ x1,
+ y1,
+ x2,
+ y2));
+ }
+
+ Status DrawLine(IN const Pen* pen,
+ IN const Point& pt1,
+ IN const Point& pt2)
+ {
+ return DrawLine(pen,
+ pt1.X,
+ pt1.Y,
+ pt2.X,
+ pt2.Y);
+ }
+
+ Status DrawLines(IN const Pen* pen,
+ IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawLinesI(nativeGraphics,
+ pen->nativePen,
+ points,
+ count));
+ }
+
+ // float version
+ Status DrawArc(IN const Pen* pen,
+ IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipDrawArc(nativeGraphics,
+ pen->nativePen,
+ x,
+ y,
+ width,
+ height,
+ startAngle,
+ sweepAngle));
+ }
+
+ Status DrawArc(IN const Pen* pen,
+ IN const RectF& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return DrawArc(pen, rect.X, rect.Y, rect.Width, rect.Height,
+ startAngle, sweepAngle);
+ }
+
+ // int version
+ Status DrawArc(IN const Pen* pen,
+ IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipDrawArcI(nativeGraphics,
+ pen->nativePen,
+ x,
+ y,
+ width,
+ height,
+ startAngle,
+ sweepAngle));
+ }
+
+
+ Status DrawArc(IN const Pen* pen,
+ IN const Rect& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return DrawArc(pen,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height,
+ startAngle,
+ sweepAngle);
+ }
+
+ // float version
+ Status DrawBezier(IN const Pen* pen,
+ IN REAL x1,
+ IN REAL y1,
+ IN REAL x2,
+ IN REAL y2,
+ IN REAL x3,
+ IN REAL y3,
+ IN REAL x4,
+ IN REAL y4)
+ {
+ return SetStatus(DllExports::GdipDrawBezier(nativeGraphics,
+ pen->nativePen, x1, y1,
+ x2, y2, x3, y3, x4, y4));
+ }
+
+ Status DrawBezier(IN const Pen* pen,
+ IN const PointF& pt1,
+ IN const PointF& pt2,
+ IN const PointF& pt3,
+ IN const PointF& pt4)
+ {
+ return DrawBezier(pen,
+ pt1.X,
+ pt1.Y,
+ pt2.X,
+ pt2.Y,
+ pt3.X,
+ pt3.Y,
+ pt4.X,
+ pt4.Y);
+ }
+
+ Status DrawBeziers(IN const Pen* pen,
+ IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawBeziers(nativeGraphics,
+ pen->nativePen,
+ points,
+ count));
+ }
+
+ // int version
+ Status DrawBezier(IN const Pen* pen,
+ IN INT x1,
+ IN INT y1,
+ IN INT x2,
+ IN INT y2,
+ IN INT x3,
+ IN INT y3,
+ IN INT x4,
+ IN INT y4)
+ {
+ return SetStatus(DllExports::GdipDrawBezierI(nativeGraphics,
+ pen->nativePen,
+ x1,
+ y1,
+ x2,
+ y2,
+ x3,
+ y3,
+ x4,
+ y4));
+ }
+
+ Status DrawBezier(IN const Pen* pen,
+ IN const Point& pt1,
+ IN const Point& pt2,
+ IN const Point& pt3,
+ IN const Point& pt4)
+ {
+ return DrawBezier(pen,
+ pt1.X,
+ pt1.Y,
+ pt2.X,
+ pt2.Y,
+ pt3.X,
+ pt3.Y,
+ pt4.X,
+ pt4.Y);
+ }
+
+ Status DrawBeziers(IN const Pen* pen,
+ IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawBeziersI(nativeGraphics,
+ pen->nativePen,
+ points,
+ count));
+ }
+
+ // float version
+ Status DrawRectangle(IN const Pen* pen,
+ IN const RectF& rect)
+ {
+ return DrawRectangle(pen, rect.X, rect.Y, rect.Width, rect.Height);
+ }
+
+ Status DrawRectangle(IN const Pen* pen,
+ IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height)
+ {
+ return SetStatus(DllExports::GdipDrawRectangle(nativeGraphics,
+ pen->nativePen, x, y,
+ width, height));
+ }
+
+ Status DrawRectangles(IN const Pen* pen,
+ IN const RectF* rects,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawRectangles(nativeGraphics,
+ pen->nativePen,
+ rects, count));
+ }
+
+ // integer version
+ Status DrawRectangle(IN const Pen* pen,
+ IN const Rect& rect)
+ {
+ return DrawRectangle(pen,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height);
+ }
+
+ Status DrawRectangle(IN const Pen* pen,
+ IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height)
+ {
+ return SetStatus(DllExports::GdipDrawRectangleI(nativeGraphics,
+ pen->nativePen,
+ x,
+ y,
+ width,
+ height));
+ }
+
+ Status DrawRectangles(IN const Pen* pen,
+ IN const Rect* rects,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawRectanglesI(nativeGraphics,
+ pen->nativePen,
+ rects,
+ count));
+ }
+
+ // float version
+ Status DrawEllipse(IN const Pen* pen,
+ IN const RectF& rect)
+ {
+ return DrawEllipse(pen, rect.X, rect.Y, rect.Width, rect.Height);
+ }
+
+ Status DrawEllipse(IN const Pen* pen,
+ IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height)
+ {
+ return SetStatus(DllExports::GdipDrawEllipse(nativeGraphics,
+ pen->nativePen,
+ x,
+ y,
+ width,
+ height));
+ }
+
+ // integer version
+ Status DrawEllipse(IN const Pen* pen,
+ IN const Rect& rect)
+ {
+ return DrawEllipse(pen,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height);
+ }
+
+ Status DrawEllipse(IN const Pen* pen,
+ IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height)
+ {
+ return SetStatus(DllExports::GdipDrawEllipseI(nativeGraphics,
+ pen->nativePen,
+ x,
+ y,
+ width,
+ height));
+ }
+
+ // floating point version
+ Status DrawPie(IN const Pen* pen,
+ IN const RectF& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return DrawPie(pen,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height,
+ startAngle,
+ sweepAngle);
+ }
+
+ Status DrawPie(IN const Pen* pen,
+ IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipDrawPie(nativeGraphics,
+ pen->nativePen,
+ x,
+ y,
+ width,
+ height,
+ startAngle,
+ sweepAngle));
+ }
+
+ // integer point version
+ Status DrawPie(IN const Pen* pen,
+ IN const Rect& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return DrawPie(pen,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height,
+ startAngle,
+ sweepAngle);
+ }
+
+ Status DrawPie(IN const Pen* pen,
+ IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipDrawPieI(nativeGraphics,
+ pen->nativePen,
+ x,
+ y,
+ width,
+ height,
+ startAngle,
+ sweepAngle));
+ }
+
+ // float version
+ Status DrawPolygon(IN const Pen* pen,
+ IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawPolygon(nativeGraphics,
+ pen->nativePen,
+ points,
+ count));
+ }
+
+ // integer version
+ Status DrawPolygon(IN const Pen* pen,
+ IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawPolygonI(nativeGraphics,
+ pen->nativePen,
+ points,
+ count));
+ }
+
+ // float version
+ Status DrawPath(IN const Pen* pen,
+ IN const GraphicsPath* path)
+ {
+ return SetStatus(DllExports::GdipDrawPath(nativeGraphics,
+ pen ? pen->nativePen : NULL,
+ path ? path->nativePath : NULL));
+ }
+
+ // float version
+ Status DrawCurve(IN const Pen* pen,
+ IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawCurve(nativeGraphics,
+ pen->nativePen, points,
+ count));
+ }
+
+ Status DrawCurve(IN const Pen* pen,
+ IN const PointF* points,
+ IN INT count,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipDrawCurve2(nativeGraphics,
+ pen->nativePen, points,
+ count, tension));
+ }
+
+ Status DrawCurve(IN const Pen* pen,
+ IN const PointF* points,
+ IN INT count,
+ IN INT offset,
+ IN INT numberOfSegments,
+ IN REAL tension = 0.5f)
+ {
+ return SetStatus(DllExports::GdipDrawCurve3(nativeGraphics,
+ pen->nativePen, points,
+ count, offset,
+ numberOfSegments, tension));
+ }
+
+ // integer version
+ Status DrawCurve(IN const Pen* pen,
+ IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawCurveI(nativeGraphics,
+ pen->nativePen,
+ points,
+ count));
+ }
+
+ Status DrawCurve(IN const Pen* pen,
+ IN const Point* points,
+ IN INT count,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipDrawCurve2I(nativeGraphics,
+ pen->nativePen,
+ points,
+ count,
+ tension));
+ }
+
+ Status DrawCurve(IN const Pen* pen,
+ IN const Point* points,
+ IN INT count,
+ IN INT offset,
+ IN INT numberOfSegments,
+ IN REAL tension = 0.5f)
+ {
+ return SetStatus(DllExports::GdipDrawCurve3I(nativeGraphics,
+ pen->nativePen,
+ points,
+ count,
+ offset,
+ numberOfSegments,
+ tension));
+ }
+
+ // float version
+ Status DrawClosedCurve(IN const Pen* pen,
+ IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawClosedCurve(nativeGraphics,
+ pen->nativePen,
+ points, count));
+ }
+
+ Status DrawClosedCurve(IN const Pen *pen,
+ IN const PointF* points,
+ IN INT count,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipDrawClosedCurve2(nativeGraphics,
+ pen->nativePen,
+ points, count,
+ tension));
+ }
+
+ // integer version
+ Status DrawClosedCurve(IN const Pen* pen,
+ IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipDrawClosedCurveI(nativeGraphics,
+ pen->nativePen,
+ points,
+ count));
+ }
+
+ Status DrawClosedCurve(IN const Pen *pen,
+ IN const Point* points,
+ IN INT count,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipDrawClosedCurve2I(nativeGraphics,
+ pen->nativePen,
+ points,
+ count,
+ tension));
+ }
+
+ Status Clear(IN const Color &color)
+ {
+ return SetStatus(DllExports::GdipGraphicsClear(
+ nativeGraphics,
+ color.GetValue()));
+ }
+
+ // float version
+ Status FillRectangle(IN const Brush* brush,
+ IN const RectF& rect)
+ {
+ return FillRectangle(brush, rect.X, rect.Y, rect.Width, rect.Height);
+ }
+
+ Status FillRectangle(IN const Brush* brush,
+ IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height)
+ {
+ return SetStatus(DllExports::GdipFillRectangle(nativeGraphics,
+ brush->nativeBrush, x, y,
+ width, height));
+ }
+
+ Status FillRectangles(IN const Brush* brush,
+ IN const RectF* rects,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipFillRectangles(nativeGraphics,
+ brush->nativeBrush,
+ rects, count));
+ }
+
+ // integer version
+ Status FillRectangle(IN const Brush* brush,
+ IN const Rect& rect)
+ {
+ return FillRectangle(brush,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height);
+ }
+
+ Status FillRectangle(IN const Brush* brush,
+ IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height)
+ {
+ return SetStatus(DllExports::GdipFillRectangleI(nativeGraphics,
+ brush->nativeBrush,
+ x,
+ y,
+ width,
+ height));
+ }
+
+ Status FillRectangles(IN const Brush* brush,
+ IN const Rect* rects,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipFillRectanglesI(nativeGraphics,
+ brush->nativeBrush,
+ rects,
+ count));
+ }
+
+ // float version
+ Status FillPolygon(IN const Brush* brush,
+ IN const PointF* points,
+ IN INT count)
+ {
+ return FillPolygon(brush, points, count, FillModeAlternate);
+ }
+
+ Status FillPolygon(IN const Brush* brush,
+ IN const PointF* points,
+ IN INT count,
+ IN FillMode fillMode)
+ {
+ return SetStatus(DllExports::GdipFillPolygon(nativeGraphics,
+ brush->nativeBrush,
+ points, count, fillMode));
+ }
+
+ // integer version
+ Status FillPolygon(IN const Brush* brush,
+ IN const Point* points,
+ IN INT count)
+ {
+ return FillPolygon(brush, points, count, FillModeAlternate);
+ }
+
+ Status FillPolygon(IN const Brush* brush,
+ IN const Point* points,
+ IN INT count,
+ IN FillMode fillMode)
+ {
+ return SetStatus(DllExports::GdipFillPolygonI(nativeGraphics,
+ brush->nativeBrush,
+ points, count,
+ fillMode));
+ }
+
+ // float version
+ Status FillEllipse(IN const Brush* brush,
+ IN const RectF& rect)
+ {
+ return FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height);
+ }
+
+ Status FillEllipse(IN const Brush* brush,
+ IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height)
+ {
+ return SetStatus(DllExports::GdipFillEllipse(nativeGraphics,
+ brush->nativeBrush, x, y,
+ width, height));
+ }
+
+ // integer version
+ Status FillEllipse(IN const Brush* brush,
+ IN const Rect& rect)
+ {
+ return FillEllipse(brush, rect.X, rect.Y, rect.Width, rect.Height);
+ }
+
+ Status FillEllipse(IN const Brush* brush,
+ IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height)
+ {
+ return SetStatus(DllExports::GdipFillEllipseI(nativeGraphics,
+ brush->nativeBrush,
+ x,
+ y,
+ width,
+ height));
+ }
+
+ // float version
+ Status FillPie(IN const Brush* brush,
+ IN const RectF& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height,
+ startAngle, sweepAngle);
+ }
+
+ Status FillPie(IN const Brush* brush,
+ IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipFillPie(nativeGraphics,
+ brush->nativeBrush, x, y,
+ width, height, startAngle,
+ sweepAngle));
+ }
+
+ // integer version
+ Status FillPie(IN const Brush* brush,
+ IN const Rect& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return FillPie(brush, rect.X, rect.Y, rect.Width, rect.Height,
+ startAngle, sweepAngle);
+ }
+
+ Status FillPie(IN const Brush* brush,
+ IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipFillPieI(nativeGraphics,
+ brush->nativeBrush,
+ x,
+ y,
+ width,
+ height,
+ startAngle,
+ sweepAngle));
+ }
+
+ Status FillPath(IN const Brush* brush,
+ IN const GraphicsPath* path)
+ {
+ return SetStatus(DllExports::GdipFillPath(nativeGraphics,
+ brush->nativeBrush,
+ path->nativePath));
+ }
+
+ // float version
+ Status FillClosedCurve(IN const Brush* brush,
+ IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipFillClosedCurve(nativeGraphics,
+ brush->nativeBrush,
+ points, count));
+
+ }
+
+ Status FillClosedCurve(IN const Brush* brush,
+ IN const PointF* points,
+ IN INT count,
+ IN FillMode fillMode,
+ IN REAL tension = 0.5f)
+ {
+ return SetStatus(DllExports::GdipFillClosedCurve2(nativeGraphics,
+ brush->nativeBrush,
+ points, count,
+ tension, fillMode));
+ }
+
+ // integer version
+ Status FillClosedCurve(IN const Brush* brush,
+ IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipFillClosedCurveI(nativeGraphics,
+ brush->nativeBrush,
+ points,
+ count));
+ }
+
+ Status FillClosedCurve(IN const Brush* brush,
+ IN const Point* points,
+ IN INT count,
+ IN FillMode fillMode,
+ IN REAL tension = 0.5f)
+ {
+ return SetStatus(DllExports::GdipFillClosedCurve2I(nativeGraphics,
+ brush->nativeBrush,
+ points, count,
+ tension, fillMode));
+ }
+
+ // float version
+ Status FillRegion(IN const Brush* brush,
+ IN const Region* region)
+ {
+ return SetStatus(DllExports::GdipFillRegion(nativeGraphics,
+ brush->nativeBrush,
+ region->nativeRegion));
+ }
+
+ // DrawString and MeasureString
+ Status
+ DrawString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const Font *font,
+ IN const RectF &layoutRect,
+ IN const StringFormat *stringFormat,
+ IN const Brush *brush
+ )
+ {
+ return SetStatus(DllExports::GdipDrawString(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ &layoutRect,
+ stringFormat ? stringFormat->nativeFormat : NULL,
+ brush ? brush->nativeBrush : NULL
+ ));
+ }
+
+ Status
+ DrawString(
+ const WCHAR *string,
+ INT length,
+ const Font *font,
+ const PointF &origin,
+ const Brush *brush
+ )
+ {
+ RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
+
+ return SetStatus(DllExports::GdipDrawString(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ &rect,
+ NULL,
+ brush ? brush->nativeBrush : NULL
+ ));
+ }
+
+ Status
+ DrawString(
+ const WCHAR *string,
+ INT length,
+ const Font *font,
+ const PointF &origin,
+ const StringFormat *stringFormat,
+ const Brush *brush
+ )
+ {
+ RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
+
+ return SetStatus(DllExports::GdipDrawString(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ &rect,
+ stringFormat ? stringFormat->nativeFormat : NULL,
+ brush ? brush->nativeBrush : NULL
+ ));
+ }
+
+ Status
+ MeasureString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const Font *font,
+ IN const RectF &layoutRect,
+ IN const StringFormat *stringFormat,
+ OUT RectF *boundingBox,
+ OUT INT *codepointsFitted = 0,
+ OUT INT *linesFilled = 0
+ ) const
+ {
+ return SetStatus(DllExports::GdipMeasureString(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ &layoutRect,
+ stringFormat ? stringFormat->nativeFormat : NULL,
+ boundingBox,
+ codepointsFitted,
+ linesFilled
+ ));
+ }
+
+ Status
+ MeasureString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const Font *font,
+ IN const SizeF &layoutRectSize,
+ IN const StringFormat *stringFormat,
+ OUT SizeF *size,
+ OUT INT *codepointsFitted = 0,
+ OUT INT *linesFilled = 0
+ ) const
+ {
+ RectF layoutRect(0, 0, layoutRectSize.Width, layoutRectSize.Height);
+ RectF boundingBox;
+ Status status;
+
+ if (size == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ status = SetStatus(DllExports::GdipMeasureString(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ &layoutRect,
+ stringFormat ? stringFormat->nativeFormat : NULL,
+ size ? &boundingBox : NULL,
+ codepointsFitted,
+ linesFilled
+ ));
+
+ if (size && status == Ok)
+ {
+ size->Width = boundingBox.Width;
+ size->Height = boundingBox.Height;
+ }
+
+ return status;
+ }
+
+ Status
+ MeasureString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const Font *font,
+ IN const PointF &origin,
+ IN const StringFormat *stringFormat,
+ OUT RectF *boundingBox
+ ) const
+ {
+ RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
+
+ return SetStatus(DllExports::GdipMeasureString(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ &rect,
+ stringFormat ? stringFormat->nativeFormat : NULL,
+ boundingBox,
+ NULL,
+ NULL
+ ));
+ }
+
+
+ Status
+ MeasureString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const Font *font,
+ IN const RectF &layoutRect,
+ OUT RectF *boundingBox
+ ) const
+ {
+ return SetStatus(DllExports::GdipMeasureString(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ &layoutRect,
+ NULL,
+ boundingBox,
+ NULL,
+ NULL
+ ));
+ }
+
+ Status
+ MeasureString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const Font *font,
+ IN const PointF &origin,
+ OUT RectF *boundingBox
+ ) const
+ {
+ RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
+
+ return SetStatus(DllExports::GdipMeasureString(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ &rect,
+ NULL,
+ boundingBox,
+ NULL,
+ NULL
+ ));
+ }
+
+
+#ifdef DCR_USE_NEW_174340
+ Status
+ MeasureCharacterRanges(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const Font *font,
+ IN const RectF &layoutRect,
+ IN const StringFormat *stringFormat,
+ IN INT regionCount,
+ OUT Region *regions
+ ) const
+ {
+ if (!regions || regionCount <= 0)
+ {
+ return InvalidParameter;
+ }
+
+ GpRegion **nativeRegions = new GpRegion* [regionCount];
+
+ if (!nativeRegions)
+ {
+ return OutOfMemory;
+ }
+
+ for (INT i = 0; i < regionCount; i++)
+ {
+ nativeRegions[i] = regions[i].nativeRegion;
+ }
+
+ Status status = SetStatus(DllExports::GdipMeasureCharacterRanges(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ layoutRect,
+ stringFormat ? stringFormat->nativeFormat : NULL,
+ regionCount,
+ nativeRegions
+ ));
+
+ delete [] nativeRegions;
+
+ return status;
+ }
+#endif
+
+
+#ifndef DCR_USE_NEW_174340
+ Status
+ MeasureStringRegion(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const Font *font,
+ IN const RectF &layoutRect,
+ IN const StringFormat *stringFormat,
+ IN INT firstCharacterIndex,
+ IN INT characterCount,
+ OUT Region *region
+ ) const
+ {
+ if (region == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ return (SetStatus(DllExports::GdipMeasureStringRegion(
+ nativeGraphics,
+ string,
+ length,
+ font ? font->nativeFont : NULL,
+ layoutRect,
+ stringFormat ? stringFormat->nativeFormat : NULL,
+ firstCharacterIndex,
+ characterCount,
+ region->nativeRegion)));
+ }
+#endif
+
+ Status DrawDriverString(
+ IN const UINT16 *text,
+ IN INT length,
+ IN const Font *font,
+ IN const Brush *brush,
+ IN const PointF *positions,
+ IN INT flags,
+ IN const Matrix *matrix
+ )
+ {
+ return SetStatus(DllExports::GdipDrawDriverString(
+ nativeGraphics,
+ text,
+ length,
+ font ? font->nativeFont : NULL,
+ brush ? brush->nativeBrush : NULL,
+ positions,
+ flags,
+ matrix ? matrix->nativeMatrix : NULL
+ ));
+ }
+
+ Status MeasureDriverString(
+ IN const UINT16 *text,
+ IN INT length,
+ IN const Font *font,
+ IN const PointF *positions,
+ IN INT flags,
+ IN const Matrix *matrix,
+ OUT RectF *boundingBox
+ ) const
+ {
+ return SetStatus(DllExports::GdipMeasureDriverString(
+ nativeGraphics,
+ text,
+ length,
+ font ? font->nativeFont : NULL,
+ positions,
+ flags,
+ matrix ? matrix->nativeMatrix : NULL,
+ boundingBox
+ ));
+ }
+
+#ifndef DCR_USE_NEW_168772
+ Status DriverStringPointToCodepoint(
+ IN const UINT16 *text,
+ IN INT length,
+ IN const Font *font,
+ IN const PointF *positions,
+ IN INT flags,
+ IN const Matrix *matrix,
+ IN const PointF &hit,
+ OUT INT *index,
+ OUT BOOL *rightEdge,
+ OUT REAL *distance
+ )
+ {
+ return SetStatus(DllExports::GdipDriverStringPointToCodepoint(
+ nativeGraphics,
+ text,
+ length,
+ font ? font->nativeFont : NULL,
+ positions,
+ flags,
+ matrix ? matrix->nativeMatrix : NULL,
+ &hit,
+ index,
+ rightEdge,
+ distance
+ ));
+ }
+#endif
+
+ // Draw a cached bitmap on this graphics destination offset by
+ // x, y. Note this will fail with WrongState if the CachedBitmap
+ // native format differs from this Graphics.
+
+ Status DrawCachedBitmap(IN CachedBitmap *cb,
+ IN INT x,
+ IN INT y)
+ {
+ return SetStatus(DllExports::GdipDrawCachedBitmap(
+ nativeGraphics,
+ cb->nativeCachedBitmap,
+ x, y
+ ));
+ }
+
+ /**
+ * Draw images (both bitmap and vector)
+ */
+ // float version
+ Status DrawImage(IN Image* image,
+ IN const PointF& point)
+ {
+ return DrawImage(image, point.X, point.Y);
+ }
+
+ Status DrawImage(IN Image* image,
+ IN REAL x,
+ IN REAL y)
+ {
+ return SetStatus(DllExports::GdipDrawImage(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ x,
+ y));
+ }
+
+ Status DrawImage(IN Image* image,
+ IN const RectF& rect)
+ {
+ return DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);
+ }
+
+ Status DrawImage(IN Image* image,
+ IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height)
+ {
+ return SetStatus(DllExports::GdipDrawImageRect(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ x,
+ y,
+ width,
+ height));
+ }
+
+ // integer version
+ Status DrawImage(IN Image* image,
+ IN const Point& point)
+ {
+ return DrawImage(image, point.X, point.Y);
+ }
+
+ Status DrawImage(IN Image* image,
+ IN INT x,
+ IN INT y)
+ {
+ return SetStatus(DllExports::GdipDrawImageI(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ x,
+ y));
+ }
+
+ Status DrawImage(IN Image* image,
+ IN const Rect& rect)
+ {
+ return DrawImage(image,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height);
+ }
+
+ Status DrawImage(IN Image* image,
+ IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height) {
+ return SetStatus(DllExports::GdipDrawImageRectI(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ x,
+ y,
+ width,
+ height));
+ }
+
+ /**
+ * Affine or perspective blt
+ * destPoints.length = 3: rect => parallelogram
+ * destPoints[0] <=> top-left corner of the source rectangle
+ * destPoints[1] <=> top-right corner
+ * destPoints[2] <=> bottom-left corner
+ * destPoints.length = 4: rect => quad
+ * destPoints[3] <=> bottom-right corner
+ *
+ * @notes Perspective blt only works for bitmap images.
+ */
+ Status DrawImage(IN Image* image,
+ IN const PointF* destPoints,
+ IN INT count)
+ {
+ if (count != 3 && count != 4)
+ return SetStatus(InvalidParameter);
+
+ return SetStatus(DllExports::GdipDrawImagePoints(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ destPoints, count));
+ }
+
+ Status DrawImage(IN Image* image,
+ IN const Point* destPoints,
+ IN INT count)
+ {
+ if (count != 3 && count != 4)
+ return SetStatus(InvalidParameter);
+
+ return SetStatus(DllExports::GdipDrawImagePointsI(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ destPoints,
+ count));
+ }
+
+ /**
+ * We need another set of methods similar to the ones above
+ * that take an additional Rect parameter to specify the
+ * portion of the source image to be drawn.
+ */
+ // float version
+ Status DrawImage(IN Image* image,
+ IN REAL x,
+ IN REAL y,
+ IN REAL srcx,
+ IN REAL srcy,
+ IN REAL srcwidth,
+ IN REAL srcheight,
+ IN Unit srcUnit)
+ {
+ return SetStatus(DllExports::GdipDrawImagePointRect(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ x, y,
+ srcx, srcy,
+ srcwidth, srcheight, srcUnit));
+ }
+
+ Status DrawImage(IN Image* image,
+ IN const RectF& destRect,
+ IN REAL srcx,
+ IN REAL srcy,
+ IN REAL srcwidth,
+ IN REAL srcheight,
+ IN Unit srcUnit,
+ IN const ImageAttributes* imageAttributes = NULL,
+ IN DrawImageAbort callback = NULL,
+ IN VOID* callbackData = NULL)
+ {
+ return SetStatus(DllExports::GdipDrawImageRectRect(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ destRect.X,
+ destRect.Y,
+ destRect.Width,
+ destRect.Height,
+ srcx, srcy,
+ srcwidth, srcheight,
+ srcUnit,
+ imageAttributes
+ ? imageAttributes->nativeImageAttr
+ : NULL,
+ callback,
+ callbackData));
+ }
+
+ Status DrawImage(IN Image* image,
+ IN const PointF* destPoints,
+ IN INT count,
+ IN REAL srcx,
+ IN REAL srcy,
+ IN REAL srcwidth,
+ IN REAL srcheight,
+ IN Unit srcUnit,
+ IN const ImageAttributes* imageAttributes = NULL,
+ IN DrawImageAbort callback = NULL,
+ IN VOID* callbackData = NULL)
+ {
+ return SetStatus(DllExports::GdipDrawImagePointsRect(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ destPoints, count,
+ srcx, srcy,
+ srcwidth,
+ srcheight,
+ srcUnit,
+ imageAttributes
+ ? imageAttributes->nativeImageAttr
+ : NULL,
+ callback,
+ callbackData));
+ }
+
+ // integer version
+ Status DrawImage(IN Image* image,
+ IN INT x,
+ IN INT y,
+ IN INT srcx,
+ IN INT srcy,
+ IN INT srcwidth,
+ IN INT srcheight,
+ IN Unit srcUnit)
+ {
+ return SetStatus(DllExports::GdipDrawImagePointRectI(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ x,
+ y,
+ srcx,
+ srcy,
+ srcwidth,
+ srcheight,
+ srcUnit));
+ }
+
+ Status DrawImage(IN Image* image,
+ IN const Rect& destRect,
+ IN INT srcx,
+ IN INT srcy,
+ IN INT srcwidth,
+ IN INT srcheight,
+ IN Unit srcUnit,
+ IN const ImageAttributes* imageAttributes = NULL,
+ IN DrawImageAbort callback = NULL,
+ IN VOID* callbackData = NULL)
+ {
+ return SetStatus(DllExports::GdipDrawImageRectRectI(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ destRect.X,
+ destRect.Y,
+ destRect.Width,
+ destRect.Height,
+ srcx,
+ srcy,
+ srcwidth,
+ srcheight,
+ srcUnit,
+ imageAttributes
+ ? imageAttributes->nativeImageAttr
+ : NULL,
+ callback,
+ callbackData));
+ }
+
+ Status DrawImage(IN Image* image,
+ IN const Point* destPoints,
+ IN INT count,
+ IN INT srcx,
+ IN INT srcy,
+ IN INT srcwidth,
+ IN INT srcheight,
+ IN Unit srcUnit,
+ IN const ImageAttributes* imageAttributes = NULL,
+ IN DrawImageAbort callback = NULL,
+ IN VOID* callbackData = NULL)
+ {
+ return SetStatus(DllExports::GdipDrawImagePointsRectI(nativeGraphics,
+ image ? image->nativeImage
+ : NULL,
+ destPoints,
+ count,
+ srcx,
+ srcy,
+ srcwidth,
+ srcheight,
+ srcUnit,
+ imageAttributes
+ ? imageAttributes->nativeImageAttr
+ : NULL,
+ callback,
+ callbackData));
+ }
+
+ // The following methods are for playing an EMF+ to a graphics
+ // via the enumeration interface. Each record of the EMF+ is
+ // sent to the callback (along with the callbackData). Then
+ // the callback can invoke the Metafile::PlayRecord method
+ // to play the particular record.
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const PointF & destPoint,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileDestPoint(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destPoint,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const Point & destPoint,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileDestPointI(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destPoint,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const RectF & destRect,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileDestRect(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destRect,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const Rect & destRect,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileDestRectI(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destRect,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const PointF * destPoints,
+ IN INT count,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileDestPoints(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destPoints,
+ count,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const Point * destPoints,
+ IN INT count,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileDestPointsI(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destPoints,
+ count,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const PointF & destPoint,
+ IN const RectF & srcRect,
+ IN Unit srcUnit,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPoint(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destPoint,
+ srcRect,
+ srcUnit,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const Point & destPoint,
+ IN const Rect & srcRect,
+ IN Unit srcUnit,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPointI(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destPoint,
+ srcRect,
+ srcUnit,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const RectF & destRect,
+ IN const RectF & srcRect,
+ IN Unit srcUnit,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestRect(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destRect,
+ srcRect,
+ srcUnit,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const Rect & destRect,
+ IN const Rect & srcRect,
+ IN Unit srcUnit,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestRectI(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destRect,
+ srcRect,
+ srcUnit,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const PointF * destPoints,
+ IN INT count,
+ IN const RectF & srcRect,
+ IN Unit srcUnit,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPoints(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destPoints,
+ count,
+ srcRect,
+ srcUnit,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ Status
+ EnumerateMetafile(
+ IN const Metafile * metafile,
+ IN const Point * destPoints,
+ IN INT count,
+ IN const Rect & srcRect,
+ IN Unit srcUnit,
+ IN EnumerateMetafileProc callback,
+ IN VOID * callbackData = NULL,
+ IN const ImageAttributes * imageAttributes = NULL
+ )
+ {
+ return SetStatus(DllExports::GdipEnumerateMetafileSrcRectDestPointsI(
+ nativeGraphics,
+ (const GpMetafile *)(metafile ? metafile->nativeImage:NULL),
+ destPoints,
+ count,
+ srcRect,
+ srcUnit,
+ callback,
+ callbackData,
+ imageAttributes ? imageAttributes->nativeImageAttr : NULL));
+ }
+
+ /**
+ * Clipping region operations
+ *
+ * @notes Simply incredible redundancy here.
+ */
+ Status SetClip(IN const Graphics* g,
+ IN CombineMode combineMode = CombineModeReplace)
+ {
+ return SetStatus(DllExports::GdipSetClipGraphics(nativeGraphics,
+ g->nativeGraphics,
+ combineMode));
+ }
+
+ Status SetClip(IN const RectF& rect,
+ IN CombineMode combineMode = CombineModeReplace)
+ {
+ return SetStatus(DllExports::GdipSetClipRect(nativeGraphics,
+ rect.X, rect.Y,
+ rect.Width, rect.Height,
+ combineMode));
+ }
+
+ Status SetClip(IN const Rect& rect,
+ IN CombineMode combineMode = CombineModeReplace)
+ {
+ return SetStatus(DllExports::GdipSetClipRectI(nativeGraphics,
+ rect.X, rect.Y,
+ rect.Width, rect.Height,
+ combineMode));
+ }
+
+ Status SetClip(IN const GraphicsPath* path,
+ IN CombineMode combineMode = CombineModeReplace)
+ {
+ return SetStatus(DllExports::GdipSetClipPath(nativeGraphics,
+ path->nativePath,
+ combineMode));
+ }
+
+ Status SetClip(IN const Region* region,
+ IN CombineMode combineMode = CombineModeReplace)
+ {
+ return SetStatus(DllExports::GdipSetClipRegion(nativeGraphics,
+ region->nativeRegion,
+ combineMode));
+ }
+
+ // This is different than the other SetClip methods because it assumes
+ // that the HRGN is already in device units, so it doesn't transform
+ // the coordinates in the HRGN.
+ Status SetClip(IN HRGN hRgn,
+ IN CombineMode combineMode = CombineModeReplace)
+ {
+ return SetStatus(DllExports::GdipSetClipHrgn(nativeGraphics, hRgn,
+ combineMode));
+ }
+
+ Status IntersectClip(IN const RectF& rect)
+ {
+ return SetStatus(DllExports::GdipSetClipRect(nativeGraphics,
+ rect.X, rect.Y,
+ rect.Width, rect.Height,
+ CombineModeIntersect));
+ }
+
+ Status IntersectClip(IN const Rect& rect)
+ {
+ return SetStatus(DllExports::GdipSetClipRectI(nativeGraphics,
+ rect.X, rect.Y,
+ rect.Width, rect.Height,
+ CombineModeIntersect));
+ }
+
+ Status IntersectClip(IN const Region* region)
+ {
+ return SetStatus(DllExports::GdipSetClipRegion(nativeGraphics,
+ region->nativeRegion,
+ CombineModeIntersect));
+ }
+
+ Status ExcludeClip(IN const RectF& rect)
+ {
+ return SetStatus(DllExports::GdipSetClipRect(nativeGraphics,
+ rect.X, rect.Y,
+ rect.Width, rect.Height,
+ CombineModeExclude));
+ }
+
+ Status ExcludeClip(IN const Rect& rect)
+ {
+ return SetStatus(DllExports::GdipSetClipRectI(nativeGraphics,
+ rect.X, rect.Y,
+ rect.Width, rect.Height,
+ CombineModeExclude));
+ }
+
+ Status ExcludeClip(IN const Region* region)
+ {
+ return SetStatus(DllExports::GdipSetClipRegion(nativeGraphics,
+ region->nativeRegion,
+ CombineModeExclude));
+ }
+
+ Status ResetClip()
+ {
+ return SetStatus(DllExports::GdipResetClip(nativeGraphics));
+ }
+
+ Status TranslateClip(IN REAL dx,
+ IN REAL dy)
+ {
+ return SetStatus(DllExports::GdipTranslateClip(nativeGraphics, dx, dy));
+ }
+
+ Status TranslateClip(IN INT dx,
+ IN INT dy)
+ {
+ return SetStatus(DllExports::GdipTranslateClipI(nativeGraphics,
+ dx, dy));
+ }
+
+ /**
+ * GetClip region from graphics context
+ */
+ Status GetClip(OUT Region* region) const
+ {
+ return SetStatus(DllExports::GdipGetClip(nativeGraphics,
+ region->nativeRegion));
+ }
+
+ /**
+ * Hit testing operations
+ */
+ Status GetClipBounds(OUT RectF* rect) const
+ {
+ return SetStatus(DllExports::GdipGetClipBounds(nativeGraphics, rect));
+ }
+
+ Status GetClipBounds(OUT Rect* rect) const
+ {
+ return SetStatus(DllExports::GdipGetClipBoundsI(nativeGraphics, rect));
+ }
+
+ BOOL IsClipEmpty() const
+ {
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsClipEmpty(nativeGraphics, &booln));
+
+ return booln;
+ }
+
+ Status GetVisibleClipBounds(OUT RectF *rect) const
+ {
+
+ return SetStatus(DllExports::GdipGetVisibleClipBounds(nativeGraphics,
+ rect));
+ }
+
+ Status GetVisibleClipBounds(OUT Rect *rect) const
+ {
+ return SetStatus(DllExports::GdipGetVisibleClipBoundsI(nativeGraphics,
+ rect));
+ }
+
+ BOOL IsVisibleClipEmpty() const
+ {
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsVisibleClipEmpty(nativeGraphics, &booln));
+
+ return booln;
+ }
+
+ BOOL IsVisible(IN INT x,
+ IN INT y) const
+ {
+ return IsVisible(Point(x,y));
+ }
+
+ BOOL IsVisible(IN const Point& point) const
+ {
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsVisiblePointI(nativeGraphics,
+ point.X,
+ point.Y,
+ &booln));
+
+ return booln;
+ }
+
+ BOOL IsVisible(IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height) const
+ {
+ return IsVisible(Rect(x, y, width, height));
+ }
+
+ BOOL IsVisible(IN const Rect& rect) const
+ {
+
+ BOOL booln = TRUE;
+
+ SetStatus(DllExports::GdipIsVisibleRectI(nativeGraphics,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height,
+ &booln));
+ return booln;
+ }
+
+ BOOL IsVisible(IN REAL x,
+ IN REAL y) const
+ {
+ return IsVisible(PointF(x, y));
+ }
+
+ BOOL IsVisible(IN const PointF& point) const
+ {
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsVisiblePoint(nativeGraphics,
+ point.X,
+ point.Y,
+ &booln));
+
+ return booln;
+ }
+
+ BOOL IsVisible(IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height) const
+ {
+ return IsVisible(RectF(x, y, width, height));
+ }
+
+ BOOL IsVisible(IN const RectF& rect) const
+ {
+ BOOL booln = TRUE;
+
+ SetStatus(DllExports::GdipIsVisibleRect(nativeGraphics,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height,
+ &booln));
+ return booln;
+ }
+
+ /**
+ * Save/restore graphics state
+ */
+ GraphicsState Save() const
+ {
+ GraphicsState gstate;
+
+ SetStatus(DllExports::GdipSaveGraphics(nativeGraphics, &gstate));
+
+ return gstate;
+ }
+
+ Status Restore(IN GraphicsState gstate)
+ {
+ return SetStatus(DllExports::GdipRestoreGraphics(nativeGraphics,
+ gstate));
+ }
+
+ /**
+ * Begin and end container drawing
+ */
+ GraphicsContainer BeginContainer(IN const RectF &dstrect,
+ IN const RectF &srcrect,
+ IN Unit unit)
+ {
+ GraphicsContainer state;
+
+ SetStatus(DllExports::GdipBeginContainer(nativeGraphics, &dstrect,
+ &srcrect, unit, &state));
+
+ return state;
+ }
+
+ /**
+ * Begin and end container drawing
+ */
+ GraphicsContainer BeginContainer(IN const Rect &dstrect,
+ IN const Rect &srcrect,
+ IN Unit unit)
+ {
+ GraphicsContainer state;
+
+ SetStatus(DllExports::GdipBeginContainerI(nativeGraphics, &dstrect,
+ &srcrect, unit, &state));
+
+ return state;
+ }
+
+ GraphicsContainer BeginContainer()
+ {
+ GraphicsContainer state;
+
+ SetStatus(DllExports::GdipBeginContainer2(nativeGraphics, &state));
+
+ return state;
+ }
+
+ Status EndContainer(IN GraphicsContainer state)
+ {
+ return SetStatus(DllExports::GdipEndContainer(nativeGraphics, state));
+ }
+
+ // only valid when recording metafiles
+ Status AddMetafileComment(IN const BYTE * data,
+ IN UINT sizeData)
+ {
+ return SetStatus(DllExports::GdipComment(nativeGraphics, sizeData, data));
+ }
+
+ /**
+ * Get/SetLayout
+ * Support for Middle East localization (right-to-left mirroring)
+ */
+ GraphicsLayout GetLayout() const
+ {
+ GraphicsLayout layout;
+
+ SetStatus(DllExports::GdipGetGraphicsLayout(nativeGraphics, &layout));
+
+ return layout;
+ }
+
+ Status SetLayout(IN const GraphicsLayout layout)
+ {
+ return SetStatus(
+ DllExports::GdipSetGraphicsLayout(nativeGraphics, layout)
+ );
+ }
+
+ static HPALETTE GetHalftonePalette()
+ {
+ return DllExports::GdipCreateHalftonePalette();
+ }
+
+ Status GetLastStatus() const
+ {
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+ }
+
+protected:
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ Graphics(const Graphics &);
+ Graphics& operator=(const Graphics &);
+protected:
+
+#else
+
+ Graphics(const Graphics& graphics)
+ {
+ graphics;
+ SetStatus(NotImplemented);
+ }
+
+ Graphics& operator=(const Graphics& graphics)
+ {
+ graphics;
+ SetStatus(NotImplemented);
+ return *this;
+ }
+
+#endif
+
+ Graphics(GpGraphics* graphics)
+ {
+ lastResult = Ok;
+ SetNativeGraphics(graphics);
+ }
+
+ VOID SetNativeGraphics(GpGraphics *graphics)
+ {
+ this->nativeGraphics = graphics;
+ }
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+ // Methods necessary to subclass Graphics for extension test.
+
+ GpGraphics* GetNativeGraphics() const
+ {
+ return this->nativeGraphics;
+ }
+
+ GpPen* GetNativePen(const Pen* pen)
+ {
+ return pen->nativePen;
+ }
+
+protected:
+ GpGraphics* nativeGraphics;
+ mutable Status lastResult;
+
+};
+
+//----------------------------------------------------------------------------
+// Extra implementation of GraphicsPath methods that use Graphics
+//----------------------------------------------------------------------------
+
+/**
+ * Get the bounds of the path object with the given transform.
+ * This is not always the tightest bounds.
+ */
+
+inline Status
+GraphicsPath::GetBounds(
+ OUT RectF* bounds,
+ IN const Matrix* matrix,
+ IN const Pen* pen) const
+{
+ GpMatrix* nativeMatrix = NULL;
+ GpPen* nativePen = NULL;
+
+ if (matrix)
+ nativeMatrix = matrix->nativeMatrix;
+
+ if (pen)
+ nativePen = pen->nativePen;
+
+ return SetStatus(DllExports::GdipGetPathWorldBounds(nativePath, bounds,
+ nativeMatrix, nativePen));
+}
+
+// integer version
+inline Status
+GraphicsPath::GetBounds(
+ OUT Rect* bounds,
+ IN const Matrix* matrix,
+ IN const Pen* pen
+) const
+{
+ GpMatrix* nativeMatrix = NULL;
+ GpPen* nativePen = NULL;
+
+ if (matrix)
+ nativeMatrix = matrix->nativeMatrix;
+
+ if (pen)
+ nativePen = pen->nativePen;
+
+ return SetStatus(DllExports::GdipGetPathWorldBoundsI(nativePath, bounds,
+ nativeMatrix, nativePen));
+}
+
+//----------------------------------------------------------------------------
+// Hit testing operations
+//----------------------------------------------------------------------------
+
+inline BOOL
+GraphicsPath::IsVisible(
+ IN REAL x,
+ IN REAL y,
+ IN const Graphics* g) const
+{
+ BOOL booln = FALSE;
+
+ GpGraphics* nativeGraphics = NULL;
+
+ if (g)
+ nativeGraphics = g->nativeGraphics;
+
+ SetStatus(DllExports::GdipIsVisiblePathPoint(nativePath,
+ x, y, nativeGraphics,
+ &booln));
+ return booln;
+}
+
+inline BOOL
+GraphicsPath::IsVisible(
+ IN INT x,
+ IN INT y,
+ IN const Graphics* g) const
+{
+ BOOL booln = FALSE;
+
+ GpGraphics* nativeGraphics = NULL;
+
+ if (g)
+ nativeGraphics = g->nativeGraphics;
+
+ SetStatus(DllExports::GdipIsVisiblePathPointI(nativePath,
+ x, y, nativeGraphics,
+ &booln));
+ return booln;
+}
+
+inline BOOL
+GraphicsPath::IsOutlineVisible(
+ IN REAL x,
+ IN REAL y,
+ IN const Pen* pen,
+ IN const Graphics* g) const
+{
+ BOOL booln = FALSE;
+
+ GpGraphics* nativeGraphics = NULL;
+ GpPen* nativePen = NULL;
+
+ if(g)
+ nativeGraphics = g->nativeGraphics;
+ if(pen)
+ nativePen = pen->nativePen;
+
+ SetStatus(DllExports::GdipIsOutlineVisiblePathPoint(nativePath,
+ x, y, nativePen, nativeGraphics,
+ &booln));
+ return booln;
+}
+
+inline BOOL
+GraphicsPath::IsOutlineVisible(
+ IN INT x,
+ IN INT y,
+ IN const Pen* pen,
+ IN const Graphics* g) const
+{
+ BOOL booln = FALSE;
+
+ GpGraphics* nativeGraphics = NULL;
+ GpPen* nativePen = NULL;
+
+ if(g)
+ nativeGraphics = g->nativeGraphics;
+ if(pen)
+ nativePen = pen->nativePen;
+
+ SetStatus(DllExports::GdipIsOutlineVisiblePathPointI(nativePath,
+ x, y, nativePen, nativeGraphics,
+ &booln));
+ return booln;
+}
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusHeaders.h b/core/src/fxge/Microsoft SDK/include/GdiPlusHeaders.h
index 215c4d09ea..9efcd89da2 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusHeaders.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusHeaders.h
@@ -1,793 +1,793 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusHeaders.h
-*
-* Abstract:
-*
-* GDI+ Native C++ public header file
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSHEADERS_H
-#define _GDIPLUSHEADERS_H
-
-//--------------------------------------------------------------------------
-// Abstract base class for regions
-//--------------------------------------------------------------------------
-
-// Include the class declarations here and have inline class implementation
-// in separate file to avoid circular references.
-
-class Region : public GdiplusBase
-{
-public:
- friend class Graphics;
-
- Region();
- Region(IN const RectF& rect);
- Region(IN const Rect& rect);
- Region(IN const GraphicsPath* path);
- Region(IN const BYTE* regionData, IN INT size);
- Region(IN HRGN hRgn);
- static Region* FromHRGN(IN HRGN hRgn);
-
- ~Region();
- Region* Clone() const;
-
- Status MakeInfinite();
- Status MakeEmpty();
-
- // Get the size of the buffer needed for the GetData method
- UINT GetDataSize() const;
-
- // buffer - where to put the data
- // bufferSize - how big the buffer is (should be at least as big as GetDataSize())
- // sizeFilled - if not NULL, this is an OUT param that says how many bytes
- // of data were written to the buffer.
- Status GetData(OUT BYTE* buffer,
- IN UINT bufferSize,
- OUT UINT* sizeFilled = NULL) const;
-
- Status Intersect(IN const Rect& rect);
- Status Intersect(IN const RectF& rect);
- Status Intersect(IN const GraphicsPath* path);
- Status Intersect(IN const Region* region);
- Status Union(IN const Rect& rect);
- Status Union(IN const RectF& rect);
- Status Union(IN const GraphicsPath* path);
- Status Union(IN const Region* region);
- Status Xor(IN const Rect& rect);
- Status Xor(IN const RectF& rect);
- Status Xor(IN const GraphicsPath* path);
- Status Xor(IN const Region* region);
- Status Exclude(IN const Rect& rect);
- Status Exclude(IN const RectF& rect);
- Status Exclude(IN const GraphicsPath* path);
- Status Exclude(IN const Region* region);
- Status Complement(IN const Rect& rect);
- Status Complement(IN const RectF& rect);
- Status Complement(IN const GraphicsPath* path);
- Status Complement(IN const Region* region);
- Status Translate(IN REAL dx,
- IN REAL dy);
- Status Translate(IN INT dx,
- IN INT dy);
- Status Transform(IN const Matrix* matrix);
-
- Status GetBounds(OUT Rect* rect,
- IN const Graphics* g) const;
-
- Status GetBounds(OUT RectF* rect,
- IN const Graphics* g) const;
-
- HRGN GetHRGN (IN const Graphics * g) const;
-
- BOOL IsEmpty(IN const Graphics *g) const;
- BOOL IsInfinite(IN const Graphics *g) const;
-
- BOOL IsVisible(IN INT x,
- IN INT y,
- IN const Graphics* g = NULL) const
- {
- return IsVisible(Point(x, y), g);
- }
-
- BOOL IsVisible(IN const Point& point,
- IN const Graphics* g = NULL) const;
-
- BOOL IsVisible(IN REAL x,
- IN REAL y,
- IN const Graphics* g = NULL) const
- {
- return IsVisible(PointF(x, y), g);
- }
-
- BOOL IsVisible(IN const PointF& point,
- IN const Graphics* g = NULL) const;
-
- BOOL IsVisible(IN INT x,
- IN INT y,
- IN INT width,
- IN INT height,
- IN const Graphics* g) const
- {
- return IsVisible(Rect(x, y, width, height), g);
- }
-
- BOOL IsVisible(IN const Rect& rect,
- IN const Graphics* g = NULL) const;
-
- BOOL IsVisible(IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height,
- IN const Graphics* g = NULL) const
- {
- return IsVisible(RectF(x, y, width, height), g);
- }
-
- BOOL IsVisible(IN const RectF& rect,
- IN const Graphics* g = NULL) const;
-
- BOOL Equals(IN const Region* region,
- IN const Graphics* g) const;
-
- UINT GetRegionScansCount(IN const Matrix* matrix) const;
- Status GetRegionScans(IN const Matrix* matrix,
- OUT RectF* rects,
- OUT INT* count) const;
- Status GetRegionScans(IN const Matrix* matrix,
- OUT Rect* rects,
- OUT INT* count) const;
- Status GetLastStatus() const;
-
-protected:
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- Region(const Region &region);
- Region& operator=(const Region &region);
-protected:
-
-#else
- Region(const Region &region)
- {
- region; // reference parameter
- SetStatus(NotImplemented);
- }
-
- Region& operator=(const Region &region)
- {
- region; // reference parameter
- SetStatus(NotImplemented);
- return *this;
- }
-#endif
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
- Region(GpRegion* nativeRegion);
-
- VOID SetNativeRegion(GpRegion* nativeRegion);
-
-protected:
- GpRegion* nativeRegion;
- mutable Status lastResult;
-};
-
-
-//--------------------------------------------------------------------------
-// Abstract base class for FontFamily
-//--------------------------------------------------------------------------
-
-class FontFamily : public GdiplusBase
-{
-public:
- friend class Font;
- friend class Graphics;
- friend class GraphicsPath;
- friend class FontCollection;
-
- FontFamily();
-
- FontFamily(
- IN const WCHAR *name,
- IN const FontCollection *fontCollection = NULL
- );
-
- ~FontFamily();
-
- static const FontFamily *GenericSansSerif();
- static const FontFamily *GenericSerif();
- static const FontFamily *GenericMonospace();
-
- Status GetFamilyName(
- OUT WCHAR name[LF_FACESIZE],
- IN LANGID language = 0
- ) const;
-
-// Copy operator
- FontFamily * Clone() const;
-
- BOOL IsAvailable() const
- {
- return (nativeFamily != NULL);
- };
-
- BOOL IsStyleAvailable(IN INT style) const;
-
- UINT16 GetEmHeight (IN INT style) const;
- UINT16 GetCellAscent (IN INT style) const;
- UINT16 GetCellDescent (IN INT style) const;
- UINT16 GetLineSpacing (IN INT style) const;
-
- ///////////////////////////////////////////////////////////
-
- Status GetLastStatus() const;
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- FontFamily(const FontFamily &);
- FontFamily& operator=(const FontFamily &);
-
-#endif
-
-protected:
- Status SetStatus(Status status) const;
-
- // private constructor for copy
- FontFamily(GpFontFamily * nativeFamily, Status status);
-
-///////////////////////////////////////
-// Data members
-protected:
-
- GpFontFamily *nativeFamily;
- mutable Status lastResult;
-};
-
-static FontFamily *GenericSansSerifFontFamily = NULL;
-static FontFamily *GenericSerifFontFamily = NULL;
-static FontFamily *GenericMonospaceFontFamily = NULL;
-
-static BYTE GenericSansSerifFontFamilyBuffer[sizeof(FontFamily)] = {0};
-static BYTE GenericSerifFontFamilyBuffer [sizeof(FontFamily)] = {0};
-static BYTE GenericMonospaceFontFamilyBuffer[sizeof(FontFamily)] = {0};
-
-
-//--------------------------------------------------------------------------
-// Abstract base class for fonts
-//--------------------------------------------------------------------------
-
-class Font : public GdiplusBase
-{
-public:
- friend class Graphics;
-
- Font(IN HDC hdc);
- Font(IN HDC hdc,
- IN const LOGFONTA* logfont);
- Font(IN HDC hdc,
- IN const LOGFONTW* logfont);
-#ifdef DCR_USE_NEW_127084
- Font(IN HDC hdc,
- IN const HFONT hfont);
-#endif
- Font(
- IN const FontFamily * family,
- IN REAL emSize,
- IN INT style = FontStyleRegular,
- IN Unit unit = UnitPoint
- );
-
- Font(
- IN const WCHAR * familyName,
- IN REAL emSize,
- IN INT style = FontStyleRegular,
- IN Unit unit = UnitPoint,
- IN const FontCollection * fontCollection = NULL
- );
-
- Status GetLogFontA(IN const Graphics* g,
- OUT LOGFONTA * logfontA) const;
- Status GetLogFontW(IN const Graphics* g,
- OUT LOGFONTW * logfontW) const;
-
- Font* Clone() const;
- ~Font();
- BOOL IsAvailable() const;
- INT GetStyle() const;
- REAL GetSize() const;
- Unit GetUnit() const;
- Status GetLastStatus() const;
- REAL GetHeight(IN const Graphics *graphics = NULL) const;
-#ifdef DCR_USE_NEW_125467
- REAL GetHeight(IN REAL dpi) const;
-#endif
-
- Status GetFamily(OUT FontFamily *family) const;
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- Font(const Font &);
- Font& operator=(const Font &);
-
-#endif
-
-protected:
- Font(GpFont* font, Status status);
- VOID SetNativeFont(GpFont *Font);
- Status SetStatus(Status status) const;
-
-protected:
- /*
- * handle to native line texture object
- */
-
- GpFont* nativeFont;
- mutable Status lastResult;
-};
-
-//--------------------------------------------------------------------------
-// Abstract base classes for font collections
-//--------------------------------------------------------------------------
-
-class FontCollection : public GdiplusBase
-{
-public:
- friend class FontFamily;
-
- FontCollection();
- virtual ~FontCollection();
-
- INT GetFamilyCount() const; // number of enumerable families in the collection
-
- Status GetFamilies( // enumerate the fonts in a collection
- IN INT numSought,
- OUT FontFamily * gpfamilies,
- OUT INT * numFound
- ) const;
-
- Status GetLastStatus() const;
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- FontCollection(const FontCollection &);
- FontCollection& operator=(const FontCollection &);
-
-#endif
-
-protected:
- Status SetStatus(Status status) const ;
-
- GpFontCollection *nativeFontCollection;
- mutable Status lastResult;
-};
-
-
-class InstalledFontCollection : public FontCollection
-{
-public:
- InstalledFontCollection();
- ~InstalledFontCollection();
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- InstalledFontCollection(const InstalledFontCollection &);
- InstalledFontCollection& operator=(const InstalledFontCollection &);
-
-#endif
-
-protected:
-#ifndef DCR_USE_NEW_235072
- Status InstallFontFile(IN const WCHAR* filename);
- Status UninstallFontFile(IN const WCHAR* filename);
-#endif
- Status SetStatus(Status status) const ;
-};
-
-
-class PrivateFontCollection : public FontCollection
-{
-public:
- PrivateFontCollection();
- ~PrivateFontCollection();
-
- Status AddFontFile(IN const WCHAR* filename);
- Status AddMemoryFont(IN const VOID* memory,
- IN INT length);
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- PrivateFontCollection(const PrivateFontCollection &);
- PrivateFontCollection& operator=(const PrivateFontCollection &);
-
-#endif
-};
-
-
-//--------------------------------------------------------------------------
-// Abstract base class for bitmap image and metafile
-//--------------------------------------------------------------------------
-
-// !!! Note:
-// Include the class declarations here and have the inline class
-// implementation in a separate file. This is done to resolve a
-// circular dependency since one of the Bitmap methods needs to
-// access the private member nativeGraphics of the Graphics object.
-
-class Image : public GdiplusBase
-{
-public:
- friend class Brush;
- friend class TextureBrush;
- friend class Graphics;
-
-#ifndef DCR_USE_NEW_140782
- Image(
- IN const WCHAR* filename
- );
-
- Image(
- IN IStream* stream
- );
-
- static Image* FromFile(
- IN const WCHAR* filename
- );
-
- static Image* FromStream(
- IN IStream* stream
- );
-#else
- Image(
- IN const WCHAR* filename,
- IN BOOL useEmbeddedColorManagement = FALSE
- );
-
- Image(
- IN IStream* stream,
- IN BOOL useEmbeddedColorManagement = FALSE
- );
-
- static Image* FromFile(
- IN const WCHAR* filename,
- IN BOOL useEmbeddedColorManagement = FALSE
- );
-
- static Image* FromStream(
- IN IStream* stream,
- IN BOOL useEmbeddedColorManagement = FALSE
- );
-#endif
-
- virtual ~Image();
- virtual Image* Clone();
-
- Status Save(IN const WCHAR* filename,
- IN const CLSID* clsidEncoder,
- IN const EncoderParameters *encoderParams = NULL);
- Status Save(IN IStream* stream,
- IN const CLSID* clsidEncoder,
- IN const EncoderParameters *encoderParams = NULL);
- Status SaveAdd(IN const EncoderParameters* encoderParams);
- Status SaveAdd(IN Image* newImage,
- IN const EncoderParameters* encoderParams);
-
- ImageType GetType() const;
- Status GetPhysicalDimension(OUT SizeF* size);
- Status GetBounds(OUT RectF* srcRect,
- OUT Unit* srcUnit);
-
- UINT GetWidth();
- UINT GetHeight();
- REAL GetHorizontalResolution();
- REAL GetVerticalResolution();
- UINT GetFlags();
- Status GetRawFormat(OUT GUID *format);
- PixelFormat GetPixelFormat();
-
- INT GetPaletteSize();
- Status GetPalette(OUT ColorPalette* palette,
- IN INT size);
- Status SetPalette(IN const ColorPalette* palette);
-
- Image* GetThumbnailImage(IN UINT thumbWidth,
- IN UINT thumbHeight,
- IN GetThumbnailImageAbort callback = NULL,
- IN VOID* callbackData = NULL);
- UINT GetFrameDimensionsCount();
- Status GetFrameDimensionsList(OUT GUID* dimensionIDs,
- IN UINT count);
- UINT GetFrameCount(IN const GUID* dimensionID);
- Status SelectActiveFrame(IN const GUID* dimensionID,
- IN UINT frameIndex);
- Status RotateFlip(IN RotateFlipType rotateFlipType);
- UINT GetPropertyCount();
- Status GetPropertyIdList(IN UINT numOfProperty,
- OUT PROPID* list);
- UINT GetPropertyItemSize(IN PROPID propId);
- Status GetPropertyItem(IN PROPID propId,
- IN UINT propSize,
- OUT PropertyItem* buffer);
- Status GetPropertySize(OUT UINT* totalBufferSize,
- OUT UINT* numProperties);
- Status GetAllPropertyItems(IN UINT totalBufferSize,
- IN UINT numProperties,
- OUT PropertyItem* allItems);
- Status RemovePropertyItem(IN PROPID propId);
- Status SetPropertyItem(IN const PropertyItem* item);
-
- UINT GetEncoderParameterListSize(IN const CLSID* clsidEncoder);
- Status GetEncoderParameterList(IN const CLSID* clsidEncoder,
- IN UINT size,
- OUT EncoderParameters* buffer);
-
- // Support for Middle East localization (right-to-left mirroring)
- ImageLayout GetLayout() const;
- Status SetLayout(IN const ImageLayout layout);
-
- Status GetLastStatus() const;
-
-protected:
-
- Image() {}
-
- Image(GpImage *nativeImage, Status status);
-
- VOID SetNativeImage(GpImage* nativeImage);
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
- GpImage* nativeImage;
- mutable Status lastResult;
- mutable Status loadStatus;
-
-#ifdef DCR_USE_NEW_250932
-
-private:
-
-#else
-
-protected:
-
-#endif
-
- // Disable copy constructor and assignment operator
-
- Image(IN const Image& C);
- Image& operator=(IN const Image& C);
-};
-
-class Bitmap : public Image
-{
-public:
- friend class Image;
- friend class CachedBitmap;
-
- Bitmap(
- IN const WCHAR *filename,
- IN BOOL useEmbeddedColorManagement = FALSE
- );
-
- Bitmap(
- IN IStream *stream,
- IN BOOL useEmbeddedColorManagement = FALSE
- );
-
- static Bitmap* FromFile(
- IN const WCHAR *filename,
- IN BOOL useEmbeddedColorManagement = FALSE
- );
-
- static Bitmap* FromStream(
- IN IStream *stream,
- IN BOOL useEmbeddedColorManagement = FALSE
- );
-
- Bitmap(IN INT width,
- IN INT height,
- IN INT stride, PixelFormat format,
- IN BYTE* scan0);
- Bitmap(IN INT width,
- IN INT height,
- IN PixelFormat format = PixelFormat32bppARGB);
- Bitmap(IN INT width,
- IN INT height,
- IN Graphics* target);
-
- Bitmap* Clone(IN const Rect& rect,
- IN PixelFormat format);
- Bitmap* Clone(IN INT x,
- IN INT y,
- IN INT width,
- IN INT height,
- IN PixelFormat format);
- Bitmap* Clone(IN const RectF& rect,
- IN PixelFormat format);
- Bitmap* Clone(IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height,
- IN PixelFormat format);
-
- Status LockBits(IN const Rect& rect,
- IN UINT flags,
- IN PixelFormat format,
- OUT BitmapData* lockedBitmapData);
- Status UnlockBits(IN BitmapData* lockedBitmapData);
- Status GetPixel(IN INT x,
- IN INT y,
- OUT Color *color);
- Status SetPixel(IN INT x,
- IN INT y,
- IN const Color &color);
- Status SetResolution(IN REAL xdpi,
- IN REAL ydpi);
-
- // GDI interop:
-
- Bitmap(IN IDirectDrawSurface7* surface);
- Bitmap(IN const BITMAPINFO* gdiBitmapInfo,
- IN VOID* gdiBitmapData);
- Bitmap(IN HBITMAP hbm,
- IN HPALETTE hpal);
- Bitmap(IN HICON hicon);
- Bitmap(IN HINSTANCE hInstance,
- IN const WCHAR * bitmapName);
- static Bitmap* FromDirectDrawSurface7(IN IDirectDrawSurface7* surface);
- static Bitmap* FromBITMAPINFO(IN const BITMAPINFO* gdiBitmapInfo,
- IN VOID* gdiBitmapData);
- static Bitmap* FromHBITMAP(IN HBITMAP hbm,
- IN HPALETTE hpal);
- static Bitmap* FromHICON(IN HICON hicon);
- static Bitmap* FromResource(IN HINSTANCE hInstance,
- IN const WCHAR * bitmapName);
-
- Status GetHBITMAP(IN const Color& colorBackground,
- OUT HBITMAP *hbmReturn);
- Status GetHICON(HICON *hicon);
-
-#ifdef DCR_USE_NEW_250932
-private:
- Bitmap(const Bitmap &);
- Bitmap& operator=(const Bitmap &);
-#endif
-
-protected:
- Bitmap(GpBitmap *nativeBitmap);
-};
-
-class CustomLineCap : public GdiplusBase
-{
-public:
- friend class Pen;
-
- CustomLineCap(
- IN const GraphicsPath* fillPath,
- IN const GraphicsPath* strokePath,
- IN LineCap baseCap = LineCapFlat,
- IN REAL baseInset = 0
- );
- virtual ~CustomLineCap();
-
- CustomLineCap* Clone() const;
-
- Status SetStrokeCap(IN LineCap strokeCap)
- {
- // This changes both start and and caps.
-
- return SetStrokeCaps(strokeCap, strokeCap);
- }
-
- Status SetStrokeCaps(IN LineCap startCap,
- IN LineCap endCap);
- Status GetStrokeCaps(OUT LineCap* startCap,
- OUT LineCap* endCap) const;
- Status SetStrokeJoin(IN LineJoin lineJoin);
- LineJoin GetStrokeJoin() const;
- Status SetBaseCap(IN LineCap baseCap);
- LineCap GetBaseCap() const;
- Status SetBaseInset(IN REAL inset);
- REAL GetBaseInset() const;
- Status SetWidthScale(IN REAL widthScale);
- REAL GetWidthScale() const;
-
-protected:
- CustomLineCap();
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- CustomLineCap(const CustomLineCap &);
- CustomLineCap& operator=(const CustomLineCap &);
-protected:
-
-#else
-
- CustomLineCap(const CustomLineCap& customLineCap)
- {
- customLineCap;
- SetStatus(NotImplemented);
- }
-
- CustomLineCap& operator=(const CustomLineCap& customLineCap)
- {
- customLineCap;
- SetStatus(NotImplemented);
- return *this;
- }
-
-#endif
-
- CustomLineCap(GpCustomLineCap* nativeCap, Status status)
- {
- lastResult = status;
- SetNativeCap(nativeCap);
- }
-
- VOID SetNativeCap(GpCustomLineCap* nativeCap)
- {
- this->nativeCap = nativeCap;
- }
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
-protected:
- GpCustomLineCap* nativeCap;
- mutable Status lastResult;
-};
-
-class CachedBitmap : public GdiplusBase
-{
- friend Graphics;
-
-public:
- CachedBitmap(IN Bitmap *bitmap,
- IN Graphics *graphics);
- virtual ~CachedBitmap();
-
- Status GetLastStatus() const;
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- CachedBitmap(const CachedBitmap &);
- CachedBitmap& operator=(const CachedBitmap &);
-
-#endif
-
-protected:
- GpCachedBitmap *nativeCachedBitmap;
- mutable Status lastResult;
-};
-
-#endif // !_GDIPLUSHEADERS.HPP
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusHeaders.h
+*
+* Abstract:
+*
+* GDI+ Native C++ public header file
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSHEADERS_H
+#define _GDIPLUSHEADERS_H
+
+//--------------------------------------------------------------------------
+// Abstract base class for regions
+//--------------------------------------------------------------------------
+
+// Include the class declarations here and have inline class implementation
+// in separate file to avoid circular references.
+
+class Region : public GdiplusBase
+{
+public:
+ friend class Graphics;
+
+ Region();
+ Region(IN const RectF& rect);
+ Region(IN const Rect& rect);
+ Region(IN const GraphicsPath* path);
+ Region(IN const BYTE* regionData, IN INT size);
+ Region(IN HRGN hRgn);
+ static Region* FromHRGN(IN HRGN hRgn);
+
+ ~Region();
+ Region* Clone() const;
+
+ Status MakeInfinite();
+ Status MakeEmpty();
+
+ // Get the size of the buffer needed for the GetData method
+ UINT GetDataSize() const;
+
+ // buffer - where to put the data
+ // bufferSize - how big the buffer is (should be at least as big as GetDataSize())
+ // sizeFilled - if not NULL, this is an OUT param that says how many bytes
+ // of data were written to the buffer.
+ Status GetData(OUT BYTE* buffer,
+ IN UINT bufferSize,
+ OUT UINT* sizeFilled = NULL) const;
+
+ Status Intersect(IN const Rect& rect);
+ Status Intersect(IN const RectF& rect);
+ Status Intersect(IN const GraphicsPath* path);
+ Status Intersect(IN const Region* region);
+ Status Union(IN const Rect& rect);
+ Status Union(IN const RectF& rect);
+ Status Union(IN const GraphicsPath* path);
+ Status Union(IN const Region* region);
+ Status Xor(IN const Rect& rect);
+ Status Xor(IN const RectF& rect);
+ Status Xor(IN const GraphicsPath* path);
+ Status Xor(IN const Region* region);
+ Status Exclude(IN const Rect& rect);
+ Status Exclude(IN const RectF& rect);
+ Status Exclude(IN const GraphicsPath* path);
+ Status Exclude(IN const Region* region);
+ Status Complement(IN const Rect& rect);
+ Status Complement(IN const RectF& rect);
+ Status Complement(IN const GraphicsPath* path);
+ Status Complement(IN const Region* region);
+ Status Translate(IN REAL dx,
+ IN REAL dy);
+ Status Translate(IN INT dx,
+ IN INT dy);
+ Status Transform(IN const Matrix* matrix);
+
+ Status GetBounds(OUT Rect* rect,
+ IN const Graphics* g) const;
+
+ Status GetBounds(OUT RectF* rect,
+ IN const Graphics* g) const;
+
+ HRGN GetHRGN (IN const Graphics * g) const;
+
+ BOOL IsEmpty(IN const Graphics *g) const;
+ BOOL IsInfinite(IN const Graphics *g) const;
+
+ BOOL IsVisible(IN INT x,
+ IN INT y,
+ IN const Graphics* g = NULL) const
+ {
+ return IsVisible(Point(x, y), g);
+ }
+
+ BOOL IsVisible(IN const Point& point,
+ IN const Graphics* g = NULL) const;
+
+ BOOL IsVisible(IN REAL x,
+ IN REAL y,
+ IN const Graphics* g = NULL) const
+ {
+ return IsVisible(PointF(x, y), g);
+ }
+
+ BOOL IsVisible(IN const PointF& point,
+ IN const Graphics* g = NULL) const;
+
+ BOOL IsVisible(IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height,
+ IN const Graphics* g) const
+ {
+ return IsVisible(Rect(x, y, width, height), g);
+ }
+
+ BOOL IsVisible(IN const Rect& rect,
+ IN const Graphics* g = NULL) const;
+
+ BOOL IsVisible(IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height,
+ IN const Graphics* g = NULL) const
+ {
+ return IsVisible(RectF(x, y, width, height), g);
+ }
+
+ BOOL IsVisible(IN const RectF& rect,
+ IN const Graphics* g = NULL) const;
+
+ BOOL Equals(IN const Region* region,
+ IN const Graphics* g) const;
+
+ UINT GetRegionScansCount(IN const Matrix* matrix) const;
+ Status GetRegionScans(IN const Matrix* matrix,
+ OUT RectF* rects,
+ OUT INT* count) const;
+ Status GetRegionScans(IN const Matrix* matrix,
+ OUT Rect* rects,
+ OUT INT* count) const;
+ Status GetLastStatus() const;
+
+protected:
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ Region(const Region &region);
+ Region& operator=(const Region &region);
+protected:
+
+#else
+ Region(const Region &region)
+ {
+ region; // reference parameter
+ SetStatus(NotImplemented);
+ }
+
+ Region& operator=(const Region &region)
+ {
+ region; // reference parameter
+ SetStatus(NotImplemented);
+ return *this;
+ }
+#endif
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+ Region(GpRegion* nativeRegion);
+
+ VOID SetNativeRegion(GpRegion* nativeRegion);
+
+protected:
+ GpRegion* nativeRegion;
+ mutable Status lastResult;
+};
+
+
+//--------------------------------------------------------------------------
+// Abstract base class for FontFamily
+//--------------------------------------------------------------------------
+
+class FontFamily : public GdiplusBase
+{
+public:
+ friend class Font;
+ friend class Graphics;
+ friend class GraphicsPath;
+ friend class FontCollection;
+
+ FontFamily();
+
+ FontFamily(
+ IN const WCHAR *name,
+ IN const FontCollection *fontCollection = NULL
+ );
+
+ ~FontFamily();
+
+ static const FontFamily *GenericSansSerif();
+ static const FontFamily *GenericSerif();
+ static const FontFamily *GenericMonospace();
+
+ Status GetFamilyName(
+ OUT WCHAR name[LF_FACESIZE],
+ IN LANGID language = 0
+ ) const;
+
+// Copy operator
+ FontFamily * Clone() const;
+
+ BOOL IsAvailable() const
+ {
+ return (nativeFamily != NULL);
+ };
+
+ BOOL IsStyleAvailable(IN INT style) const;
+
+ UINT16 GetEmHeight (IN INT style) const;
+ UINT16 GetCellAscent (IN INT style) const;
+ UINT16 GetCellDescent (IN INT style) const;
+ UINT16 GetLineSpacing (IN INT style) const;
+
+ ///////////////////////////////////////////////////////////
+
+ Status GetLastStatus() const;
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ FontFamily(const FontFamily &);
+ FontFamily& operator=(const FontFamily &);
+
+#endif
+
+protected:
+ Status SetStatus(Status status) const;
+
+ // private constructor for copy
+ FontFamily(GpFontFamily * nativeFamily, Status status);
+
+///////////////////////////////////////
+// Data members
+protected:
+
+ GpFontFamily *nativeFamily;
+ mutable Status lastResult;
+};
+
+static FontFamily *GenericSansSerifFontFamily = NULL;
+static FontFamily *GenericSerifFontFamily = NULL;
+static FontFamily *GenericMonospaceFontFamily = NULL;
+
+static BYTE GenericSansSerifFontFamilyBuffer[sizeof(FontFamily)] = {0};
+static BYTE GenericSerifFontFamilyBuffer [sizeof(FontFamily)] = {0};
+static BYTE GenericMonospaceFontFamilyBuffer[sizeof(FontFamily)] = {0};
+
+
+//--------------------------------------------------------------------------
+// Abstract base class for fonts
+//--------------------------------------------------------------------------
+
+class Font : public GdiplusBase
+{
+public:
+ friend class Graphics;
+
+ Font(IN HDC hdc);
+ Font(IN HDC hdc,
+ IN const LOGFONTA* logfont);
+ Font(IN HDC hdc,
+ IN const LOGFONTW* logfont);
+#ifdef DCR_USE_NEW_127084
+ Font(IN HDC hdc,
+ IN const HFONT hfont);
+#endif
+ Font(
+ IN const FontFamily * family,
+ IN REAL emSize,
+ IN INT style = FontStyleRegular,
+ IN Unit unit = UnitPoint
+ );
+
+ Font(
+ IN const WCHAR * familyName,
+ IN REAL emSize,
+ IN INT style = FontStyleRegular,
+ IN Unit unit = UnitPoint,
+ IN const FontCollection * fontCollection = NULL
+ );
+
+ Status GetLogFontA(IN const Graphics* g,
+ OUT LOGFONTA * logfontA) const;
+ Status GetLogFontW(IN const Graphics* g,
+ OUT LOGFONTW * logfontW) const;
+
+ Font* Clone() const;
+ ~Font();
+ BOOL IsAvailable() const;
+ INT GetStyle() const;
+ REAL GetSize() const;
+ Unit GetUnit() const;
+ Status GetLastStatus() const;
+ REAL GetHeight(IN const Graphics *graphics = NULL) const;
+#ifdef DCR_USE_NEW_125467
+ REAL GetHeight(IN REAL dpi) const;
+#endif
+
+ Status GetFamily(OUT FontFamily *family) const;
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ Font(const Font &);
+ Font& operator=(const Font &);
+
+#endif
+
+protected:
+ Font(GpFont* font, Status status);
+ VOID SetNativeFont(GpFont *Font);
+ Status SetStatus(Status status) const;
+
+protected:
+ /*
+ * handle to native line texture object
+ */
+
+ GpFont* nativeFont;
+ mutable Status lastResult;
+};
+
+//--------------------------------------------------------------------------
+// Abstract base classes for font collections
+//--------------------------------------------------------------------------
+
+class FontCollection : public GdiplusBase
+{
+public:
+ friend class FontFamily;
+
+ FontCollection();
+ virtual ~FontCollection();
+
+ INT GetFamilyCount() const; // number of enumerable families in the collection
+
+ Status GetFamilies( // enumerate the fonts in a collection
+ IN INT numSought,
+ OUT FontFamily * gpfamilies,
+ OUT INT * numFound
+ ) const;
+
+ Status GetLastStatus() const;
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ FontCollection(const FontCollection &);
+ FontCollection& operator=(const FontCollection &);
+
+#endif
+
+protected:
+ Status SetStatus(Status status) const ;
+
+ GpFontCollection *nativeFontCollection;
+ mutable Status lastResult;
+};
+
+
+class InstalledFontCollection : public FontCollection
+{
+public:
+ InstalledFontCollection();
+ ~InstalledFontCollection();
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ InstalledFontCollection(const InstalledFontCollection &);
+ InstalledFontCollection& operator=(const InstalledFontCollection &);
+
+#endif
+
+protected:
+#ifndef DCR_USE_NEW_235072
+ Status InstallFontFile(IN const WCHAR* filename);
+ Status UninstallFontFile(IN const WCHAR* filename);
+#endif
+ Status SetStatus(Status status) const ;
+};
+
+
+class PrivateFontCollection : public FontCollection
+{
+public:
+ PrivateFontCollection();
+ ~PrivateFontCollection();
+
+ Status AddFontFile(IN const WCHAR* filename);
+ Status AddMemoryFont(IN const VOID* memory,
+ IN INT length);
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ PrivateFontCollection(const PrivateFontCollection &);
+ PrivateFontCollection& operator=(const PrivateFontCollection &);
+
+#endif
+};
+
+
+//--------------------------------------------------------------------------
+// Abstract base class for bitmap image and metafile
+//--------------------------------------------------------------------------
+
+// !!! Note:
+// Include the class declarations here and have the inline class
+// implementation in a separate file. This is done to resolve a
+// circular dependency since one of the Bitmap methods needs to
+// access the private member nativeGraphics of the Graphics object.
+
+class Image : public GdiplusBase
+{
+public:
+ friend class Brush;
+ friend class TextureBrush;
+ friend class Graphics;
+
+#ifndef DCR_USE_NEW_140782
+ Image(
+ IN const WCHAR* filename
+ );
+
+ Image(
+ IN IStream* stream
+ );
+
+ static Image* FromFile(
+ IN const WCHAR* filename
+ );
+
+ static Image* FromStream(
+ IN IStream* stream
+ );
+#else
+ Image(
+ IN const WCHAR* filename,
+ IN BOOL useEmbeddedColorManagement = FALSE
+ );
+
+ Image(
+ IN IStream* stream,
+ IN BOOL useEmbeddedColorManagement = FALSE
+ );
+
+ static Image* FromFile(
+ IN const WCHAR* filename,
+ IN BOOL useEmbeddedColorManagement = FALSE
+ );
+
+ static Image* FromStream(
+ IN IStream* stream,
+ IN BOOL useEmbeddedColorManagement = FALSE
+ );
+#endif
+
+ virtual ~Image();
+ virtual Image* Clone();
+
+ Status Save(IN const WCHAR* filename,
+ IN const CLSID* clsidEncoder,
+ IN const EncoderParameters *encoderParams = NULL);
+ Status Save(IN IStream* stream,
+ IN const CLSID* clsidEncoder,
+ IN const EncoderParameters *encoderParams = NULL);
+ Status SaveAdd(IN const EncoderParameters* encoderParams);
+ Status SaveAdd(IN Image* newImage,
+ IN const EncoderParameters* encoderParams);
+
+ ImageType GetType() const;
+ Status GetPhysicalDimension(OUT SizeF* size);
+ Status GetBounds(OUT RectF* srcRect,
+ OUT Unit* srcUnit);
+
+ UINT GetWidth();
+ UINT GetHeight();
+ REAL GetHorizontalResolution();
+ REAL GetVerticalResolution();
+ UINT GetFlags();
+ Status GetRawFormat(OUT GUID *format);
+ PixelFormat GetPixelFormat();
+
+ INT GetPaletteSize();
+ Status GetPalette(OUT ColorPalette* palette,
+ IN INT size);
+ Status SetPalette(IN const ColorPalette* palette);
+
+ Image* GetThumbnailImage(IN UINT thumbWidth,
+ IN UINT thumbHeight,
+ IN GetThumbnailImageAbort callback = NULL,
+ IN VOID* callbackData = NULL);
+ UINT GetFrameDimensionsCount();
+ Status GetFrameDimensionsList(OUT GUID* dimensionIDs,
+ IN UINT count);
+ UINT GetFrameCount(IN const GUID* dimensionID);
+ Status SelectActiveFrame(IN const GUID* dimensionID,
+ IN UINT frameIndex);
+ Status RotateFlip(IN RotateFlipType rotateFlipType);
+ UINT GetPropertyCount();
+ Status GetPropertyIdList(IN UINT numOfProperty,
+ OUT PROPID* list);
+ UINT GetPropertyItemSize(IN PROPID propId);
+ Status GetPropertyItem(IN PROPID propId,
+ IN UINT propSize,
+ OUT PropertyItem* buffer);
+ Status GetPropertySize(OUT UINT* totalBufferSize,
+ OUT UINT* numProperties);
+ Status GetAllPropertyItems(IN UINT totalBufferSize,
+ IN UINT numProperties,
+ OUT PropertyItem* allItems);
+ Status RemovePropertyItem(IN PROPID propId);
+ Status SetPropertyItem(IN const PropertyItem* item);
+
+ UINT GetEncoderParameterListSize(IN const CLSID* clsidEncoder);
+ Status GetEncoderParameterList(IN const CLSID* clsidEncoder,
+ IN UINT size,
+ OUT EncoderParameters* buffer);
+
+ // Support for Middle East localization (right-to-left mirroring)
+ ImageLayout GetLayout() const;
+ Status SetLayout(IN const ImageLayout layout);
+
+ Status GetLastStatus() const;
+
+protected:
+
+ Image() {}
+
+ Image(GpImage *nativeImage, Status status);
+
+ VOID SetNativeImage(GpImage* nativeImage);
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+ GpImage* nativeImage;
+ mutable Status lastResult;
+ mutable Status loadStatus;
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+
+#else
+
+protected:
+
+#endif
+
+ // Disable copy constructor and assignment operator
+
+ Image(IN const Image& C);
+ Image& operator=(IN const Image& C);
+};
+
+class Bitmap : public Image
+{
+public:
+ friend class Image;
+ friend class CachedBitmap;
+
+ Bitmap(
+ IN const WCHAR *filename,
+ IN BOOL useEmbeddedColorManagement = FALSE
+ );
+
+ Bitmap(
+ IN IStream *stream,
+ IN BOOL useEmbeddedColorManagement = FALSE
+ );
+
+ static Bitmap* FromFile(
+ IN const WCHAR *filename,
+ IN BOOL useEmbeddedColorManagement = FALSE
+ );
+
+ static Bitmap* FromStream(
+ IN IStream *stream,
+ IN BOOL useEmbeddedColorManagement = FALSE
+ );
+
+ Bitmap(IN INT width,
+ IN INT height,
+ IN INT stride, PixelFormat format,
+ IN BYTE* scan0);
+ Bitmap(IN INT width,
+ IN INT height,
+ IN PixelFormat format = PixelFormat32bppARGB);
+ Bitmap(IN INT width,
+ IN INT height,
+ IN Graphics* target);
+
+ Bitmap* Clone(IN const Rect& rect,
+ IN PixelFormat format);
+ Bitmap* Clone(IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height,
+ IN PixelFormat format);
+ Bitmap* Clone(IN const RectF& rect,
+ IN PixelFormat format);
+ Bitmap* Clone(IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height,
+ IN PixelFormat format);
+
+ Status LockBits(IN const Rect& rect,
+ IN UINT flags,
+ IN PixelFormat format,
+ OUT BitmapData* lockedBitmapData);
+ Status UnlockBits(IN BitmapData* lockedBitmapData);
+ Status GetPixel(IN INT x,
+ IN INT y,
+ OUT Color *color);
+ Status SetPixel(IN INT x,
+ IN INT y,
+ IN const Color &color);
+ Status SetResolution(IN REAL xdpi,
+ IN REAL ydpi);
+
+ // GDI interop:
+
+ Bitmap(IN IDirectDrawSurface7* surface);
+ Bitmap(IN const BITMAPINFO* gdiBitmapInfo,
+ IN VOID* gdiBitmapData);
+ Bitmap(IN HBITMAP hbm,
+ IN HPALETTE hpal);
+ Bitmap(IN HICON hicon);
+ Bitmap(IN HINSTANCE hInstance,
+ IN const WCHAR * bitmapName);
+ static Bitmap* FromDirectDrawSurface7(IN IDirectDrawSurface7* surface);
+ static Bitmap* FromBITMAPINFO(IN const BITMAPINFO* gdiBitmapInfo,
+ IN VOID* gdiBitmapData);
+ static Bitmap* FromHBITMAP(IN HBITMAP hbm,
+ IN HPALETTE hpal);
+ static Bitmap* FromHICON(IN HICON hicon);
+ static Bitmap* FromResource(IN HINSTANCE hInstance,
+ IN const WCHAR * bitmapName);
+
+ Status GetHBITMAP(IN const Color& colorBackground,
+ OUT HBITMAP *hbmReturn);
+ Status GetHICON(HICON *hicon);
+
+#ifdef DCR_USE_NEW_250932
+private:
+ Bitmap(const Bitmap &);
+ Bitmap& operator=(const Bitmap &);
+#endif
+
+protected:
+ Bitmap(GpBitmap *nativeBitmap);
+};
+
+class CustomLineCap : public GdiplusBase
+{
+public:
+ friend class Pen;
+
+ CustomLineCap(
+ IN const GraphicsPath* fillPath,
+ IN const GraphicsPath* strokePath,
+ IN LineCap baseCap = LineCapFlat,
+ IN REAL baseInset = 0
+ );
+ virtual ~CustomLineCap();
+
+ CustomLineCap* Clone() const;
+
+ Status SetStrokeCap(IN LineCap strokeCap)
+ {
+ // This changes both start and and caps.
+
+ return SetStrokeCaps(strokeCap, strokeCap);
+ }
+
+ Status SetStrokeCaps(IN LineCap startCap,
+ IN LineCap endCap);
+ Status GetStrokeCaps(OUT LineCap* startCap,
+ OUT LineCap* endCap) const;
+ Status SetStrokeJoin(IN LineJoin lineJoin);
+ LineJoin GetStrokeJoin() const;
+ Status SetBaseCap(IN LineCap baseCap);
+ LineCap GetBaseCap() const;
+ Status SetBaseInset(IN REAL inset);
+ REAL GetBaseInset() const;
+ Status SetWidthScale(IN REAL widthScale);
+ REAL GetWidthScale() const;
+
+protected:
+ CustomLineCap();
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ CustomLineCap(const CustomLineCap &);
+ CustomLineCap& operator=(const CustomLineCap &);
+protected:
+
+#else
+
+ CustomLineCap(const CustomLineCap& customLineCap)
+ {
+ customLineCap;
+ SetStatus(NotImplemented);
+ }
+
+ CustomLineCap& operator=(const CustomLineCap& customLineCap)
+ {
+ customLineCap;
+ SetStatus(NotImplemented);
+ return *this;
+ }
+
+#endif
+
+ CustomLineCap(GpCustomLineCap* nativeCap, Status status)
+ {
+ lastResult = status;
+ SetNativeCap(nativeCap);
+ }
+
+ VOID SetNativeCap(GpCustomLineCap* nativeCap)
+ {
+ this->nativeCap = nativeCap;
+ }
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+protected:
+ GpCustomLineCap* nativeCap;
+ mutable Status lastResult;
+};
+
+class CachedBitmap : public GdiplusBase
+{
+ friend Graphics;
+
+public:
+ CachedBitmap(IN Bitmap *bitmap,
+ IN Graphics *graphics);
+ virtual ~CachedBitmap();
+
+ Status GetLastStatus() const;
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ CachedBitmap(const CachedBitmap &);
+ CachedBitmap& operator=(const CachedBitmap &);
+
+#endif
+
+protected:
+ GpCachedBitmap *nativeCachedBitmap;
+ mutable Status lastResult;
+};
+
+#endif // !_GDIPLUSHEADERS.HPP
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusImageCodec.h b/core/src/fxge/Microsoft SDK/include/GdiPlusImageCodec.h
index e9c02deb7e..d9ea0386b2 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusImageCodec.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusImageCodec.h
@@ -1,73 +1,73 @@
-/**************************************************************************\
-*
-* Copyright (c) 2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusImageCodec.h
-*
-* Abstract:
-*
-* APIs for imaging codecs.
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSIMAGECODEC_H
-#define _GDIPLUSIMAGECODEC_H
-
-//--------------------------------------------------------------------------
-// Codec Management APIs
-//--------------------------------------------------------------------------
-
-inline Status
-GetImageDecodersSize(
- OUT UINT *numDecoders,
- OUT UINT *size)
-{
- return DllExports::GdipGetImageDecodersSize(numDecoders, size);
-}
-
-
-inline Status
-GetImageDecoders(
- IN UINT numDecoders,
- IN UINT size,
- OUT ImageCodecInfo *decoders)
-{
- return DllExports::GdipGetImageDecoders(numDecoders, size, decoders);
-}
-
-
-inline Status
-GetImageEncodersSize(
- OUT UINT *numEncoders,
- OUT UINT *size)
-{
- return DllExports::GdipGetImageEncodersSize(numEncoders, size);
-}
-
-
-inline Status
-GetImageEncoders(
- IN UINT numEncoders,
- IN UINT size,
- OUT ImageCodecInfo *encoders)
-{
- return DllExports::GdipGetImageEncoders(numEncoders, size, encoders);
-}
-
-inline Status
-AddImageCodec(
- IN const ImageCodecInfo* codec)
-{
- return DllExports::GdipAddImageCodec(codec);
-}
-
-inline Status
-RemoveImageCodec(
- IN const ImageCodecInfo* codec)
-{
- return DllExports::GdipRemoveImageCodec(codec);
-}
-
-#endif // _GDIPLUSIMAGECODEC_H
+/**************************************************************************\
+*
+* Copyright (c) 2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusImageCodec.h
+*
+* Abstract:
+*
+* APIs for imaging codecs.
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSIMAGECODEC_H
+#define _GDIPLUSIMAGECODEC_H
+
+//--------------------------------------------------------------------------
+// Codec Management APIs
+//--------------------------------------------------------------------------
+
+inline Status
+GetImageDecodersSize(
+ OUT UINT *numDecoders,
+ OUT UINT *size)
+{
+ return DllExports::GdipGetImageDecodersSize(numDecoders, size);
+}
+
+
+inline Status
+GetImageDecoders(
+ IN UINT numDecoders,
+ IN UINT size,
+ OUT ImageCodecInfo *decoders)
+{
+ return DllExports::GdipGetImageDecoders(numDecoders, size, decoders);
+}
+
+
+inline Status
+GetImageEncodersSize(
+ OUT UINT *numEncoders,
+ OUT UINT *size)
+{
+ return DllExports::GdipGetImageEncodersSize(numEncoders, size);
+}
+
+
+inline Status
+GetImageEncoders(
+ IN UINT numEncoders,
+ IN UINT size,
+ OUT ImageCodecInfo *encoders)
+{
+ return DllExports::GdipGetImageEncoders(numEncoders, size, encoders);
+}
+
+inline Status
+AddImageCodec(
+ IN const ImageCodecInfo* codec)
+{
+ return DllExports::GdipAddImageCodec(codec);
+}
+
+inline Status
+RemoveImageCodec(
+ IN const ImageCodecInfo* codec)
+{
+ return DllExports::GdipRemoveImageCodec(codec);
+}
+
+#endif // _GDIPLUSIMAGECODEC_H
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusImaging.h b/core/src/fxge/Microsoft SDK/include/GdiPlusImaging.h
index 35dd4d0634..d6bd4f0d18 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusImaging.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusImaging.h
@@ -1,540 +1,540 @@
-/**************************************************************************\
-*
-* Copyright (c) 1999-2000 Microsoft Corporation
-*
-* Module Name:
-*
-* GdiplusImaging.h
-*
-* Abstract:
-*
-* GUIDs defined and used by the imaging library
-*
-\**************************************************************************/
-#ifndef _GDIPLUSIMAGING_H
-#define _GDIPLUSIMAGING_H
-
-//---------------------------------------------------------------------------
-// Image file format identifiers
-//---------------------------------------------------------------------------
-
-DEFINE_GUID(ImageFormatUndefined, 0xb96b3ca9,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatMemoryBMP, 0xb96b3caa,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatBMP, 0xb96b3cab,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatEMF, 0xb96b3cac,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatWMF, 0xb96b3cad,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatJPEG, 0xb96b3cae,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatPNG, 0xb96b3caf,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatGIF, 0xb96b3cb0,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatTIFF, 0xb96b3cb1,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatEXIF, 0xb96b3cb2,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-#ifndef DCR_USE_NEW_140855
-DEFINE_GUID(ImageFormatPhotoCD, 0xb96b3cb3,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-DEFINE_GUID(ImageFormatFlashPIX, 0xb96b3cb4,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-#endif
-DEFINE_GUID(ImageFormatIcon, 0xb96b3cb5,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
-
-//---------------------------------------------------------------------------
-// Predefined multi-frame dimension IDs
-//---------------------------------------------------------------------------
-
-DEFINE_GUID(FrameDimensionTime, 0x6aedbd6d,0x3fb5,0x418a,0x83,0xa6,0x7f,0x45,0x22,0x9d,0xc8,0x72);
-DEFINE_GUID(FrameDimensionResolution, 0x84236f7b,0x3bd3,0x428f,0x8d,0xab,0x4e,0xa1,0x43,0x9c,0xa3,0x15);
-DEFINE_GUID(FrameDimensionPage, 0x7462dc86,0x6180,0x4c7e,0x8e,0x3f,0xee,0x73,0x33,0xa7,0xa4,0x83);
-
-//---------------------------------------------------------------------------
-// Property sets
-//---------------------------------------------------------------------------
-
-DEFINE_GUID(FormatIDImageInformation, 0xe5836cbe,0x5eef,0x4f1d,0xac,0xde,0xae,0x4c,0x43,0xb6,0x08,0xce);
-DEFINE_GUID(FormatIDJpegAppHeaders, 0x1c4afdcd,0x6177,0x43cf,0xab,0xc7,0x5f,0x51,0xaf,0x39,0xee,0x85);
-
-#ifndef DCR_USE_NEW_140855
-//---------------------------------------------------------------------------
-// Decoder parameter sets
-//---------------------------------------------------------------------------
-DEFINE_GUID(DecoderTransColor, 0xb7a98c8f,0xdce7,0x457d,0xbf,0xa5,0xce,0xa7,0x1b,0xd1,0x4d,0xd6);
-DEFINE_GUID(DecoderTransRange, 0xabeed189,0xd988,0x4d03,0xb4,0x25,0x57,0x10,0x55,0xc7,0x6a,0xd1);
-DEFINE_GUID(DecoderOutputChannel, 0x2ff8f51e,0x724d,0x45fe,0x86,0xce,0x17,0x77,0xa0,0x56,0xda,0x60);
-DEFINE_GUID(DecoderIconRes, 0x5c656eec,0xe94f,0x45ba,0xa6,0xf6,0x10,0x62,0xe8,0x5f,0x4a,0x7f);
-#endif
-
-//---------------------------------------------------------------------------
-// Encoder parameter sets
-//---------------------------------------------------------------------------
-
-DEFINE_GUID(EncoderCompression, 0xe09d739d,0xccd4,0x44ee,0x8e,0xba,0x3f,0xbf,0x8b,0xe4,0xfc,0x58);
-DEFINE_GUID(EncoderColorDepth, 0x66087055,0xad66,0x4c7c,0x9a,0x18,0x38,0xa2,0x31,0x0b,0x83,0x37);
-DEFINE_GUID(EncoderScanMethod, 0x3a4e2661,0x3109,0x4e56,0x85,0x36,0x42,0xc1,0x56,0xe7,0xdc,0xfa);
-DEFINE_GUID(EncoderVersion, 0x24d18c76,0x814a,0x41a4,0xbf,0x53,0x1c,0x21,0x9c,0xcc,0xf7,0x97);
-DEFINE_GUID(EncoderRenderMethod, 0x6d42c53a,0x229a,0x4825,0x8b,0xb7,0x5c,0x99,0xe2,0xb9,0xa8,0xb8);
-DEFINE_GUID(EncoderQuality, 0x1d5be4b5,0xfa4a,0x452d,0x9c,0xdd,0x5d,0xb3,0x51,0x05,0xe7,0xeb);
-DEFINE_GUID(EncoderTransformation,0x8d0eb2d1,0xa58e,0x4ea8,0xaa,0x14,0x10,0x80,0x74,0xb7,0xb6,0xf9);
-DEFINE_GUID(EncoderLuminanceTable,0xedb33bce,0x0266,0x4a77,0xb9,0x04,0x27,0x21,0x60,0x99,0xe7,0x17);
-DEFINE_GUID(EncoderChrominanceTable,0xf2e455dc,0x09b3,0x4316,0x82,0x60,0x67,0x6a,0xda,0x32,0x48,0x1c);
-DEFINE_GUID(EncoderSaveFlag,0x292266fc,0xac40,0x47bf,0x8c, 0xfc, 0xa8, 0x5b, 0x89, 0xa6, 0x55, 0xde);
-
-DEFINE_GUID(CodecIImageBytes,0x025d1823,0x6c7d,0x447b,0xbb, 0xdb, 0xa3, 0xcb, 0xc3, 0xdf, 0xa2, 0xfc);
-
-MIDL_INTERFACE("025D1823-6C7D-447B-BBDB-A3CBC3DFA2FC")
-IImageBytes : public IUnknown
-{
-public:
- // Return total number of bytes in the IStream
-
- STDMETHOD(CountBytes)(
- OUT UINT *pcb
- ) = 0;
-
- // Locks "cb" bytes, starting from "ulOffset" in the stream, and returns the
- // pointer to the beginning of the locked memory chunk in "ppvBytes"
-
- STDMETHOD(LockBytes)(
- IN UINT cb,
- IN ULONG ulOffset,
- OUT const VOID ** ppvBytes
- ) = 0;
-
- // Unlocks "cb" bytes, pointed by "pvBytes", starting from "ulOffset" in the
- // stream
-
- STDMETHOD(UnlockBytes)(
- IN const VOID *pvBytes,
- IN UINT cb,
- IN ULONG ulOffset
- ) = 0;
-};
-
-//--------------------------------------------------------------------------
-// ImageCodecInfo structure
-//--------------------------------------------------------------------------
-
-class ImageCodecInfo
-{
-public:
- CLSID Clsid;
- GUID FormatID;
- const WCHAR* CodecName;
- const WCHAR* DllName;
- const WCHAR* FormatDescription;
- const WCHAR* FilenameExtension;
- const WCHAR* MimeType;
- DWORD Flags;
- DWORD Version;
- DWORD SigCount;
- DWORD SigSize;
- const BYTE* SigPattern;
- const BYTE* SigMask;
-};
-
-//--------------------------------------------------------------------------
-// Information flags about image codecs
-//--------------------------------------------------------------------------
-
-enum ImageCodecFlags
-{
- ImageCodecFlagsEncoder = 0x00000001,
- ImageCodecFlagsDecoder = 0x00000002,
- ImageCodecFlagsSupportBitmap = 0x00000004,
- ImageCodecFlagsSupportVector = 0x00000008,
- ImageCodecFlagsSeekableEncode = 0x00000010,
- ImageCodecFlagsBlockingDecode = 0x00000020,
-
- ImageCodecFlagsBuiltin = 0x00010000,
- ImageCodecFlagsSystem = 0x00020000,
- ImageCodecFlagsUser = 0x00040000
-};
-
-//---------------------------------------------------------------------------
-// Access modes used when calling Image::LockBits
-//---------------------------------------------------------------------------
-
-enum ImageLockMode
-{
- ImageLockModeRead = 0x0001,
- ImageLockModeWrite = 0x0002,
- ImageLockModeUserInputBuf= 0x0004
-};
-
-//---------------------------------------------------------------------------
-// Information about image pixel data
-//---------------------------------------------------------------------------
-
-class BitmapData
-{
-public:
- UINT Width;
- UINT Height;
- INT Stride;
- PixelFormat PixelFormat;
- VOID* Scan0;
- UINT_PTR Reserved;
-};
-
-//---------------------------------------------------------------------------
-// Image flags
-//---------------------------------------------------------------------------
-
-enum ImageFlags
-{
- ImageFlagsNone = 0,
-
- // Low-word: shared with SINKFLAG_x
-
- ImageFlagsScalable = 0x0001,
- ImageFlagsHasAlpha = 0x0002,
- ImageFlagsHasTranslucent = 0x0004,
- ImageFlagsPartiallyScalable = 0x0008,
-
- // Low-word: color space definition
-
- ImageFlagsColorSpaceRGB = 0x0010,
- ImageFlagsColorSpaceCMYK = 0x0020,
- ImageFlagsColorSpaceGRAY = 0x0040,
- ImageFlagsColorSpaceYCBCR = 0x0080,
- ImageFlagsColorSpaceYCCK = 0x0100,
-
- // Low-word: image size info
-
- ImageFlagsHasRealDPI = 0x1000,
- ImageFlagsHasRealPixelSize = 0x2000,
-
- // High-word
-
- ImageFlagsReadOnly = 0x00010000,
- ImageFlagsCaching = 0x00020000
-};
-
-enum RotateFlipType
-{
- RotateNoneFlipNone = 0,
- Rotate90FlipNone = 1,
- Rotate180FlipNone = 2,
- Rotate270FlipNone = 3,
-
- RotateNoneFlipX = 4,
- Rotate90FlipX = 5,
- Rotate180FlipX = 6,
- Rotate270FlipX = 7,
-
- RotateNoneFlipY = Rotate180FlipX,
- Rotate90FlipY = Rotate270FlipX,
- Rotate180FlipY = RotateNoneFlipX,
- Rotate270FlipY = Rotate90FlipX,
-
- RotateNoneFlipXY = Rotate180FlipNone,
- Rotate90FlipXY = Rotate270FlipNone,
- Rotate180FlipXY = RotateNoneFlipNone,
- Rotate270FlipXY = Rotate90FlipNone
-};
-
-//---------------------------------------------------------------------------
-// Encoder Parameter structure
-//---------------------------------------------------------------------------
-class EncoderParameter
-{
-public:
- GUID Guid; // GUID of the parameter
- ULONG NumberOfValues; // Number of the parameter values
- ULONG Type; // Value type, like ValueTypeLONG etc.
- VOID* Value; // A pointer to the parameter values
-};
-
-//---------------------------------------------------------------------------
-// Encoder Parameters structure
-//---------------------------------------------------------------------------
-class EncoderParameters
-{
-public:
- UINT Count; // Number of parameters in this structure
- EncoderParameter Parameter[1]; // Parameter values
-};
-
-//---------------------------------------------------------------------------
-// Property Item
-//---------------------------------------------------------------------------
-class PropertyItem
-{
-public:
- PROPID id; // ID of this property
- ULONG length; // Length of the property value, in bytes
- WORD type; // Type of the value, as one of TAG_TYPE_XXX
- // defined above
- VOID* value; // property value
-};
-
-#ifdef DCR_USE_NEW_140857
-//---------------------------------------------------------------------------
-// Image property types
-//---------------------------------------------------------------------------
-#define PropertyTagTypeByte 1
-#define PropertyTagTypeASCII 2
-#define PropertyTagTypeShort 3
-#define PropertyTagTypeLong 4
-#define PropertyTagTypeRational 5
-#define PropertyTagTypeUndefined 7
-#define PropertyTagTypeSLONG 9
-#define PropertyTagTypeSRational 10
-#endif
-
-//---------------------------------------------------------------------------
-// Image property ID tags
-//---------------------------------------------------------------------------
-
-#define PropertyTagExifIFD 0x8769
-#define PropertyTagGpsIFD 0x8825
-
-#define PropertyTagNewSubfileType 0x00FE
-#define PropertyTagSubfileType 0x00FF
-#define PropertyTagImageWidth 0x0100
-#define PropertyTagImageHeight 0x0101
-#define PropertyTagBitsPerSample 0x0102
-#define PropertyTagCompression 0x0103
-#define PropertyTagPhotometricInterp 0x0106
-#define PropertyTagThreshHolding 0x0107
-#define PropertyTagCellWidth 0x0108
-#define PropertyTagCellHeight 0x0109
-#define PropertyTagFillOrder 0x010A
-#define PropertyTagDocumentName 0x010D
-#define PropertyTagImageDescription 0x010E
-#define PropertyTagEquipMake 0x010F
-#define PropertyTagEquipModel 0x0110
-#define PropertyTagStripOffsets 0x0111
-#define PropertyTagOrientation 0x0112
-#define PropertyTagSamplesPerPixel 0x0115
-#define PropertyTagRowsPerStrip 0x0116
-#define PropertyTagStripBytesCount 0x0117
-#define PropertyTagMinSampleValue 0x0118
-#define PropertyTagMaxSampleValue 0x0119
-#define PropertyTagXResolution 0x011A // Image resolution in width direction
-#define PropertyTagYResolution 0x011B // Image resolution in height direction
-#define PropertyTagPlanarConfig 0x011C // Image data arrangement
-#define PropertyTagPageName 0x011D
-#define PropertyTagXPosition 0x011E
-#define PropertyTagYPosition 0x011F
-#define PropertyTagFreeOffset 0x0120
-#define PropertyTagFreeByteCounts 0x0121
-#define PropertyTagGrayResponseUnit 0x0122
-#define PropertyTagGrayResponseCurve 0x0123
-#define PropertyTagT4Option 0x0124
-#define PropertyTagT6Option 0x0125
-#define PropertyTagResolutionUnit 0x0128 // Unit of X and Y resolution
-#define PropertyTagPageNumber 0x0129
-#define PropertyTagTransferFuncition 0x012D
-#define PropertyTagSoftwareUsed 0x0131
-#define PropertyTagDateTime 0x0132
-#define PropertyTagArtist 0x013B
-#define PropertyTagHostComputer 0x013C
-#define PropertyTagPredictor 0x013D
-#define PropertyTagWhitePoint 0x013E
-#define PropertyTagPrimaryChromaticities 0x013F
-#define PropertyTagColorMap 0x0140
-#define PropertyTagHalftoneHints 0x0141
-#define PropertyTagTileWidth 0x0142
-#define PropertyTagTileLength 0x0143
-#define PropertyTagTileOffset 0x0144
-#define PropertyTagTileByteCounts 0x0145
-#define PropertyTagInkSet 0x014C
-#define PropertyTagInkNames 0x014D
-#define PropertyTagNumberOfInks 0x014E
-#define PropertyTagDotRange 0x0150
-#define PropertyTagTargetPrinter 0x0151
-#define PropertyTagExtraSamples 0x0152
-#define PropertyTagSampleFormat 0x0153
-#define PropertyTagSMinSampleValue 0x0154
-#define PropertyTagSMaxSampleValue 0x0155
-#define PropertyTagTransferRange 0x0156
-
-#define PropertyTagJPEGProc 0x0200
-#define PropertyTagJPEGInterFormat 0x0201
-#define PropertyTagJPEGInterLength 0x0202
-#define PropertyTagJPEGRestartInterval 0x0203
-#define PropertyTagJPEGLosslessPredictors 0x0205
-#define PropertyTagJPEGPointTransforms 0x0206
-#define PropertyTagJPEGQTables 0x0207
-#define PropertyTagJPEGDCTables 0x0208
-#define PropertyTagJPEGACTables 0x0209
-
-#define PropertyTagYCbCrCoefficients 0x0211
-#define PropertyTagYCbCrSubsampling 0x0212
-#define PropertyTagYCbCrPositioning 0x0213
-#define PropertyTagREFBlackWhite 0x0214
-
-#define PropertyTagICCProfile 0x8773 // This TAG is defined by ICC
- // for embedded ICC in TIFF
-#define PropertyTagGamma 0x0301
-#define PropertyTagICCProfileDescriptor 0x0302
-#define PropertyTagSRGBRenderingIntent 0x0303
-
-#define PropertyTagImageTitle 0x0320
-#define PropertyTagCopyright 0x8298
-
-// Extra TAGs (Like Adobe Image Information tags etc.)
-
-#define PropertyTagResolutionXUnit 0x5001
-#define PropertyTagResolutionYUnit 0x5002
-#define PropertyTagResolutionXLengthUnit 0x5003
-#define PropertyTagResolutionYLengthUnit 0x5004
-#define PropertyTagPrintFlags 0x5005
-#define PropertyTagPrintFlagsVersion 0x5006
-#define PropertyTagPrintFlagsCrop 0x5007
-#define PropertyTagPrintFlagsBleedWidth 0x5008
-#define PropertyTagPrintFlagsBleedWidthScale 0x5009
-#define PropertyTagHalftoneLPI 0x500A
-#define PropertyTagHalftoneLPIUnit 0x500B
-#define PropertyTagHalftoneDegree 0x500C
-#define PropertyTagHalftoneShape 0x500D
-#define PropertyTagHalftoneMisc 0x500E
-#define PropertyTagHalftoneScreen 0x500F
-#define PropertyTagJPEGQuality 0x5010
-#define PropertyTagGridSize 0x5011
-#define PropertyTagThumbnailFormat 0x5012 // 1 = JPEG, 0 = RAW RGB
-#define PropertyTagThumbnailWidth 0x5013
-#define PropertyTagThumbnailHeight 0x5014
-#define PropertyTagThumbnailColorDepth 0x5015
-#define PropertyTagThumbnailPlanes 0x5016
-#define PropertyTagThumbnailRawBytes 0x5017
-#define PropertyTagThumbnailSize 0x5018
-#define PropertyTagThumbnailCompressedSize 0x5019
-#define PropertyTagColorTransferFunction 0x501A
-#define PropertyTagThumbnailData 0x501B// RAW thumbnail bits in
- // JPEG format or RGB format
- // depends on
- // PropertyTagThumbnailFormat
-
-// Thumbnail related TAGs
-
-#define PropertyTagThumbnailImageWidth 0x5020 // Thumbnail width
-#define PropertyTagThumbnailImageHeight 0x5021 // Thumbnail height
-#define PropertyTagThumbnailBitsPerSample 0x5022 // Number of bits per
- // component
-#define PropertyTagThumbnailCompression 0x5023 // Compression Scheme
-#define PropertyTagThumbnailPhotometricInterp 0x5024 // Pixel composition
-#define PropertyTagThumbnailImageDescription 0x5025 // Image Tile
-#define PropertyTagThumbnailEquipMake 0x5026 // Manufacturer of Image
- // Input equipment
-#define PropertyTagThumbnailEquipModel 0x5027 // Model of Image input
- // equipment
-#define PropertyTagThumbnailStripOffsets 0x5028 // Image data location
-#define PropertyTagThumbnailOrientation 0x5029 // Orientation of image
-#define PropertyTagThumbnailSamplesPerPixel 0x502A // Number of components
-#define PropertyTagThumbnailRowsPerStrip 0x502B // Number of rows per strip
-#define PropertyTagThumbnailStripBytesCount 0x502C // Bytes per compressed
- // strip
-#define PropertyTagThumbnailResolutionX 0x502D // Resolution in width
- // direction
-#define PropertyTagThumbnailResolutionY 0x502E // Resolution in height
- // direction
-#define PropertyTagThumbnailPlanarConfig 0x502F // Image data arrangement
-#define PropertyTagThumbnailResolutionUnit 0x5030 // Unit of X and Y
- // Resolution
-#define PropertyTagThumbnailTransferFunction 0x5031 // Transfer function
-#define PropertyTagThumbnailSoftwareUsed 0x5032 // Software used
-#define PropertyTagThumbnailDateTime 0x5033 // File change date and
- // time
-#define PropertyTagThumbnailArtist 0x5034 // Person who created the
- // image
-#define PropertyTagThumbnailWhitePoint 0x5035 // White point chromaticity
-#define PropertyTagThumbnailPrimaryChromaticities 0x5036
- // Chromaticities of
- // primaries
-#define PropertyTagThumbnailYCbCrCoefficients 0x5037 // Color space transforma-
- // tion coefficients
-#define PropertyTagThumbnailYCbCrSubsampling 0x5038 // Subsampling ratio of Y
- // to C
-#define PropertyTagThumbnailYCbCrPositioning 0x5039 // Y and C position
-#define PropertyTagThumbnailRefBlackWhite 0x503A // Pair of black and white
- // reference values
-#define PropertyTagThumbnailCopyRight 0x503B // CopyRight holder
-
-#define PropertyTagLuminanceTable 0x5090
-#define PropertyTagChrominanceTable 0x5091
-
-#define PropertyTagFrameDelay 0x5100
-#define PropertyTagLoopCount 0x5101
-
-#define PropertyTagPixelUnit 0x5110 // Unit specifier for pixel/unit
-#define PropertyTagPixelPerUnitX 0x5111 // Pixels per unit in X
-#define PropertyTagPixelPerUnitY 0x5112 // Pixels per unit in Y
-#define PropertyTagPaletteHistogram 0x5113 // Palette histogram
-
-// EXIF specific tag
-
-#define PropertyTagExifExposureTime 0x829A
-#define PropertyTagExifFNumber 0x829D
-
-#define PropertyTagExifExposureProg 0x8822
-#define PropertyTagExifSpectralSense 0x8824
-#define PropertyTagExifISOSpeed 0x8827
-#define PropertyTagExifOECF 0x8828
-
-#define PropertyTagExifVer 0x9000
-#define PropertyTagExifDTOrig 0x9003 // Date & time of original
-#define PropertyTagExifDTDigitized 0x9004 // Date & time of digital data generation
-
-#define PropertyTagExifCompConfig 0x9101
-#define PropertyTagExifCompBPP 0x9102
-
-#define PropertyTagExifShutterSpeed 0x9201
-#define PropertyTagExifAperture 0x9202
-#define PropertyTagExifBrightness 0x9203
-#define PropertyTagExifExposureBias 0x9204
-#define PropertyTagExifMaxAperture 0x9205
-#define PropertyTagExifSubjectDist 0x9206
-#define PropertyTagExifMeteringMode 0x9207
-#define PropertyTagExifLightSource 0x9208
-#define PropertyTagExifFlash 0x9209
-#define PropertyTagExifFocalLength 0x920A
-#define PropertyTagExifMakerNote 0x927C
-#define PropertyTagExifUserComment 0x9286
-#define PropertyTagExifDTSubsec 0x9290 // Date & Time subseconds
-#define PropertyTagExifDTOrigSS 0x9291 // Date & Time original subseconds
-#define PropertyTagExifDTDigSS 0x9292 // Date & TIme digitized subseconds
-
-#define PropertyTagExifFPXVer 0xA000
-#define PropertyTagExifColorSpace 0xA001
-#define PropertyTagExifPixXDim 0xA002
-#define PropertyTagExifPixYDim 0xA003
-#define PropertyTagExifRelatedWav 0xA004 // related sound file
-#define PropertyTagExifInterop 0xA005
-#define PropertyTagExifFlashEnergy 0xA20B
-#define PropertyTagExifSpatialFR 0xA20C // Spatial Frequency Response
-#define PropertyTagExifFocalXRes 0xA20E // Focal Plane X Resolution
-#define PropertyTagExifFocalYRes 0xA20F // Focal Plane Y Resolution
-#define PropertyTagExifFocalResUnit 0xA210 // Focal Plane Resolution Unit
-#define PropertyTagExifSubjectLoc 0xA214
-#define PropertyTagExifExposureIndex 0xA215
-#define PropertyTagExifSensingMethod 0xA217
-#define PropertyTagExifFileSource 0xA300
-#define PropertyTagExifSceneType 0xA301
-#define PropertyTagExifCfaPattern 0xA302
-
-#define PropertyTagGpsVer 0x0000
-#define PropertyTagGpsLatitudeRef 0x0001
-#define PropertyTagGpsLatitude 0x0002
-#define PropertyTagGpsLongitudeRef 0x0003
-#define PropertyTagGpsLongitude 0x0004
-#define PropertyTagGpsAltitudeRef 0x0005
-#define PropertyTagGpsAltitude 0x0006
-#define PropertyTagGpsGpsTime 0x0007
-#define PropertyTagGpsGpsSatellites 0x0008
-#define PropertyTagGpsGpsStatus 0x0009
-#define PropertyTagGpsGpsMeasureMode 0x00A
-#define PropertyTagGpsGpsDop 0x000B // Measurement precision
-#define PropertyTagGpsSpeedRef 0x000C
-#define PropertyTagGpsSpeed 0x000D
-#define PropertyTagGpsTrackRef 0x000E
-#define PropertyTagGpsTrack 0x000F
-#define PropertyTagGpsImgDirRef 0x0010
-#define PropertyTagGpsImgDir 0x0011
-#define PropertyTagGpsMapDatum 0x0012
-#define PropertyTagGpsDestLatRef 0x0013
-#define PropertyTagGpsDestLat 0x0014
-#define PropertyTagGpsDestLongRef 0x0015
-#define PropertyTagGpsDestLong 0x0016
-#define PropertyTagGpsDestBearRef 0x0017
-#define PropertyTagGpsDestBear 0x0018
-#define PropertyTagGpsDestDistRef 0x0019
-#define PropertyTagGpsDestDist 0x001A
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1999-2000 Microsoft Corporation
+*
+* Module Name:
+*
+* GdiplusImaging.h
+*
+* Abstract:
+*
+* GUIDs defined and used by the imaging library
+*
+\**************************************************************************/
+#ifndef _GDIPLUSIMAGING_H
+#define _GDIPLUSIMAGING_H
+
+//---------------------------------------------------------------------------
+// Image file format identifiers
+//---------------------------------------------------------------------------
+
+DEFINE_GUID(ImageFormatUndefined, 0xb96b3ca9,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatMemoryBMP, 0xb96b3caa,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatBMP, 0xb96b3cab,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatEMF, 0xb96b3cac,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatWMF, 0xb96b3cad,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatJPEG, 0xb96b3cae,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatPNG, 0xb96b3caf,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatGIF, 0xb96b3cb0,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatTIFF, 0xb96b3cb1,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatEXIF, 0xb96b3cb2,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+#ifndef DCR_USE_NEW_140855
+DEFINE_GUID(ImageFormatPhotoCD, 0xb96b3cb3,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+DEFINE_GUID(ImageFormatFlashPIX, 0xb96b3cb4,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+#endif
+DEFINE_GUID(ImageFormatIcon, 0xb96b3cb5,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e);
+
+//---------------------------------------------------------------------------
+// Predefined multi-frame dimension IDs
+//---------------------------------------------------------------------------
+
+DEFINE_GUID(FrameDimensionTime, 0x6aedbd6d,0x3fb5,0x418a,0x83,0xa6,0x7f,0x45,0x22,0x9d,0xc8,0x72);
+DEFINE_GUID(FrameDimensionResolution, 0x84236f7b,0x3bd3,0x428f,0x8d,0xab,0x4e,0xa1,0x43,0x9c,0xa3,0x15);
+DEFINE_GUID(FrameDimensionPage, 0x7462dc86,0x6180,0x4c7e,0x8e,0x3f,0xee,0x73,0x33,0xa7,0xa4,0x83);
+
+//---------------------------------------------------------------------------
+// Property sets
+//---------------------------------------------------------------------------
+
+DEFINE_GUID(FormatIDImageInformation, 0xe5836cbe,0x5eef,0x4f1d,0xac,0xde,0xae,0x4c,0x43,0xb6,0x08,0xce);
+DEFINE_GUID(FormatIDJpegAppHeaders, 0x1c4afdcd,0x6177,0x43cf,0xab,0xc7,0x5f,0x51,0xaf,0x39,0xee,0x85);
+
+#ifndef DCR_USE_NEW_140855
+//---------------------------------------------------------------------------
+// Decoder parameter sets
+//---------------------------------------------------------------------------
+DEFINE_GUID(DecoderTransColor, 0xb7a98c8f,0xdce7,0x457d,0xbf,0xa5,0xce,0xa7,0x1b,0xd1,0x4d,0xd6);
+DEFINE_GUID(DecoderTransRange, 0xabeed189,0xd988,0x4d03,0xb4,0x25,0x57,0x10,0x55,0xc7,0x6a,0xd1);
+DEFINE_GUID(DecoderOutputChannel, 0x2ff8f51e,0x724d,0x45fe,0x86,0xce,0x17,0x77,0xa0,0x56,0xda,0x60);
+DEFINE_GUID(DecoderIconRes, 0x5c656eec,0xe94f,0x45ba,0xa6,0xf6,0x10,0x62,0xe8,0x5f,0x4a,0x7f);
+#endif
+
+//---------------------------------------------------------------------------
+// Encoder parameter sets
+//---------------------------------------------------------------------------
+
+DEFINE_GUID(EncoderCompression, 0xe09d739d,0xccd4,0x44ee,0x8e,0xba,0x3f,0xbf,0x8b,0xe4,0xfc,0x58);
+DEFINE_GUID(EncoderColorDepth, 0x66087055,0xad66,0x4c7c,0x9a,0x18,0x38,0xa2,0x31,0x0b,0x83,0x37);
+DEFINE_GUID(EncoderScanMethod, 0x3a4e2661,0x3109,0x4e56,0x85,0x36,0x42,0xc1,0x56,0xe7,0xdc,0xfa);
+DEFINE_GUID(EncoderVersion, 0x24d18c76,0x814a,0x41a4,0xbf,0x53,0x1c,0x21,0x9c,0xcc,0xf7,0x97);
+DEFINE_GUID(EncoderRenderMethod, 0x6d42c53a,0x229a,0x4825,0x8b,0xb7,0x5c,0x99,0xe2,0xb9,0xa8,0xb8);
+DEFINE_GUID(EncoderQuality, 0x1d5be4b5,0xfa4a,0x452d,0x9c,0xdd,0x5d,0xb3,0x51,0x05,0xe7,0xeb);
+DEFINE_GUID(EncoderTransformation,0x8d0eb2d1,0xa58e,0x4ea8,0xaa,0x14,0x10,0x80,0x74,0xb7,0xb6,0xf9);
+DEFINE_GUID(EncoderLuminanceTable,0xedb33bce,0x0266,0x4a77,0xb9,0x04,0x27,0x21,0x60,0x99,0xe7,0x17);
+DEFINE_GUID(EncoderChrominanceTable,0xf2e455dc,0x09b3,0x4316,0x82,0x60,0x67,0x6a,0xda,0x32,0x48,0x1c);
+DEFINE_GUID(EncoderSaveFlag,0x292266fc,0xac40,0x47bf,0x8c, 0xfc, 0xa8, 0x5b, 0x89, 0xa6, 0x55, 0xde);
+
+DEFINE_GUID(CodecIImageBytes,0x025d1823,0x6c7d,0x447b,0xbb, 0xdb, 0xa3, 0xcb, 0xc3, 0xdf, 0xa2, 0xfc);
+
+MIDL_INTERFACE("025D1823-6C7D-447B-BBDB-A3CBC3DFA2FC")
+IImageBytes : public IUnknown
+{
+public:
+ // Return total number of bytes in the IStream
+
+ STDMETHOD(CountBytes)(
+ OUT UINT *pcb
+ ) = 0;
+
+ // Locks "cb" bytes, starting from "ulOffset" in the stream, and returns the
+ // pointer to the beginning of the locked memory chunk in "ppvBytes"
+
+ STDMETHOD(LockBytes)(
+ IN UINT cb,
+ IN ULONG ulOffset,
+ OUT const VOID ** ppvBytes
+ ) = 0;
+
+ // Unlocks "cb" bytes, pointed by "pvBytes", starting from "ulOffset" in the
+ // stream
+
+ STDMETHOD(UnlockBytes)(
+ IN const VOID *pvBytes,
+ IN UINT cb,
+ IN ULONG ulOffset
+ ) = 0;
+};
+
+//--------------------------------------------------------------------------
+// ImageCodecInfo structure
+//--------------------------------------------------------------------------
+
+class ImageCodecInfo
+{
+public:
+ CLSID Clsid;
+ GUID FormatID;
+ const WCHAR* CodecName;
+ const WCHAR* DllName;
+ const WCHAR* FormatDescription;
+ const WCHAR* FilenameExtension;
+ const WCHAR* MimeType;
+ DWORD Flags;
+ DWORD Version;
+ DWORD SigCount;
+ DWORD SigSize;
+ const BYTE* SigPattern;
+ const BYTE* SigMask;
+};
+
+//--------------------------------------------------------------------------
+// Information flags about image codecs
+//--------------------------------------------------------------------------
+
+enum ImageCodecFlags
+{
+ ImageCodecFlagsEncoder = 0x00000001,
+ ImageCodecFlagsDecoder = 0x00000002,
+ ImageCodecFlagsSupportBitmap = 0x00000004,
+ ImageCodecFlagsSupportVector = 0x00000008,
+ ImageCodecFlagsSeekableEncode = 0x00000010,
+ ImageCodecFlagsBlockingDecode = 0x00000020,
+
+ ImageCodecFlagsBuiltin = 0x00010000,
+ ImageCodecFlagsSystem = 0x00020000,
+ ImageCodecFlagsUser = 0x00040000
+};
+
+//---------------------------------------------------------------------------
+// Access modes used when calling Image::LockBits
+//---------------------------------------------------------------------------
+
+enum ImageLockMode
+{
+ ImageLockModeRead = 0x0001,
+ ImageLockModeWrite = 0x0002,
+ ImageLockModeUserInputBuf= 0x0004
+};
+
+//---------------------------------------------------------------------------
+// Information about image pixel data
+//---------------------------------------------------------------------------
+
+class BitmapData
+{
+public:
+ UINT Width;
+ UINT Height;
+ INT Stride;
+ PixelFormat PixelFormat;
+ VOID* Scan0;
+ UINT_PTR Reserved;
+};
+
+//---------------------------------------------------------------------------
+// Image flags
+//---------------------------------------------------------------------------
+
+enum ImageFlags
+{
+ ImageFlagsNone = 0,
+
+ // Low-word: shared with SINKFLAG_x
+
+ ImageFlagsScalable = 0x0001,
+ ImageFlagsHasAlpha = 0x0002,
+ ImageFlagsHasTranslucent = 0x0004,
+ ImageFlagsPartiallyScalable = 0x0008,
+
+ // Low-word: color space definition
+
+ ImageFlagsColorSpaceRGB = 0x0010,
+ ImageFlagsColorSpaceCMYK = 0x0020,
+ ImageFlagsColorSpaceGRAY = 0x0040,
+ ImageFlagsColorSpaceYCBCR = 0x0080,
+ ImageFlagsColorSpaceYCCK = 0x0100,
+
+ // Low-word: image size info
+
+ ImageFlagsHasRealDPI = 0x1000,
+ ImageFlagsHasRealPixelSize = 0x2000,
+
+ // High-word
+
+ ImageFlagsReadOnly = 0x00010000,
+ ImageFlagsCaching = 0x00020000
+};
+
+enum RotateFlipType
+{
+ RotateNoneFlipNone = 0,
+ Rotate90FlipNone = 1,
+ Rotate180FlipNone = 2,
+ Rotate270FlipNone = 3,
+
+ RotateNoneFlipX = 4,
+ Rotate90FlipX = 5,
+ Rotate180FlipX = 6,
+ Rotate270FlipX = 7,
+
+ RotateNoneFlipY = Rotate180FlipX,
+ Rotate90FlipY = Rotate270FlipX,
+ Rotate180FlipY = RotateNoneFlipX,
+ Rotate270FlipY = Rotate90FlipX,
+
+ RotateNoneFlipXY = Rotate180FlipNone,
+ Rotate90FlipXY = Rotate270FlipNone,
+ Rotate180FlipXY = RotateNoneFlipNone,
+ Rotate270FlipXY = Rotate90FlipNone
+};
+
+//---------------------------------------------------------------------------
+// Encoder Parameter structure
+//---------------------------------------------------------------------------
+class EncoderParameter
+{
+public:
+ GUID Guid; // GUID of the parameter
+ ULONG NumberOfValues; // Number of the parameter values
+ ULONG Type; // Value type, like ValueTypeLONG etc.
+ VOID* Value; // A pointer to the parameter values
+};
+
+//---------------------------------------------------------------------------
+// Encoder Parameters structure
+//---------------------------------------------------------------------------
+class EncoderParameters
+{
+public:
+ UINT Count; // Number of parameters in this structure
+ EncoderParameter Parameter[1]; // Parameter values
+};
+
+//---------------------------------------------------------------------------
+// Property Item
+//---------------------------------------------------------------------------
+class PropertyItem
+{
+public:
+ PROPID id; // ID of this property
+ ULONG length; // Length of the property value, in bytes
+ WORD type; // Type of the value, as one of TAG_TYPE_XXX
+ // defined above
+ VOID* value; // property value
+};
+
+#ifdef DCR_USE_NEW_140857
+//---------------------------------------------------------------------------
+// Image property types
+//---------------------------------------------------------------------------
+#define PropertyTagTypeByte 1
+#define PropertyTagTypeASCII 2
+#define PropertyTagTypeShort 3
+#define PropertyTagTypeLong 4
+#define PropertyTagTypeRational 5
+#define PropertyTagTypeUndefined 7
+#define PropertyTagTypeSLONG 9
+#define PropertyTagTypeSRational 10
+#endif
+
+//---------------------------------------------------------------------------
+// Image property ID tags
+//---------------------------------------------------------------------------
+
+#define PropertyTagExifIFD 0x8769
+#define PropertyTagGpsIFD 0x8825
+
+#define PropertyTagNewSubfileType 0x00FE
+#define PropertyTagSubfileType 0x00FF
+#define PropertyTagImageWidth 0x0100
+#define PropertyTagImageHeight 0x0101
+#define PropertyTagBitsPerSample 0x0102
+#define PropertyTagCompression 0x0103
+#define PropertyTagPhotometricInterp 0x0106
+#define PropertyTagThreshHolding 0x0107
+#define PropertyTagCellWidth 0x0108
+#define PropertyTagCellHeight 0x0109
+#define PropertyTagFillOrder 0x010A
+#define PropertyTagDocumentName 0x010D
+#define PropertyTagImageDescription 0x010E
+#define PropertyTagEquipMake 0x010F
+#define PropertyTagEquipModel 0x0110
+#define PropertyTagStripOffsets 0x0111
+#define PropertyTagOrientation 0x0112
+#define PropertyTagSamplesPerPixel 0x0115
+#define PropertyTagRowsPerStrip 0x0116
+#define PropertyTagStripBytesCount 0x0117
+#define PropertyTagMinSampleValue 0x0118
+#define PropertyTagMaxSampleValue 0x0119
+#define PropertyTagXResolution 0x011A // Image resolution in width direction
+#define PropertyTagYResolution 0x011B // Image resolution in height direction
+#define PropertyTagPlanarConfig 0x011C // Image data arrangement
+#define PropertyTagPageName 0x011D
+#define PropertyTagXPosition 0x011E
+#define PropertyTagYPosition 0x011F
+#define PropertyTagFreeOffset 0x0120
+#define PropertyTagFreeByteCounts 0x0121
+#define PropertyTagGrayResponseUnit 0x0122
+#define PropertyTagGrayResponseCurve 0x0123
+#define PropertyTagT4Option 0x0124
+#define PropertyTagT6Option 0x0125
+#define PropertyTagResolutionUnit 0x0128 // Unit of X and Y resolution
+#define PropertyTagPageNumber 0x0129
+#define PropertyTagTransferFuncition 0x012D
+#define PropertyTagSoftwareUsed 0x0131
+#define PropertyTagDateTime 0x0132
+#define PropertyTagArtist 0x013B
+#define PropertyTagHostComputer 0x013C
+#define PropertyTagPredictor 0x013D
+#define PropertyTagWhitePoint 0x013E
+#define PropertyTagPrimaryChromaticities 0x013F
+#define PropertyTagColorMap 0x0140
+#define PropertyTagHalftoneHints 0x0141
+#define PropertyTagTileWidth 0x0142
+#define PropertyTagTileLength 0x0143
+#define PropertyTagTileOffset 0x0144
+#define PropertyTagTileByteCounts 0x0145
+#define PropertyTagInkSet 0x014C
+#define PropertyTagInkNames 0x014D
+#define PropertyTagNumberOfInks 0x014E
+#define PropertyTagDotRange 0x0150
+#define PropertyTagTargetPrinter 0x0151
+#define PropertyTagExtraSamples 0x0152
+#define PropertyTagSampleFormat 0x0153
+#define PropertyTagSMinSampleValue 0x0154
+#define PropertyTagSMaxSampleValue 0x0155
+#define PropertyTagTransferRange 0x0156
+
+#define PropertyTagJPEGProc 0x0200
+#define PropertyTagJPEGInterFormat 0x0201
+#define PropertyTagJPEGInterLength 0x0202
+#define PropertyTagJPEGRestartInterval 0x0203
+#define PropertyTagJPEGLosslessPredictors 0x0205
+#define PropertyTagJPEGPointTransforms 0x0206
+#define PropertyTagJPEGQTables 0x0207
+#define PropertyTagJPEGDCTables 0x0208
+#define PropertyTagJPEGACTables 0x0209
+
+#define PropertyTagYCbCrCoefficients 0x0211
+#define PropertyTagYCbCrSubsampling 0x0212
+#define PropertyTagYCbCrPositioning 0x0213
+#define PropertyTagREFBlackWhite 0x0214
+
+#define PropertyTagICCProfile 0x8773 // This TAG is defined by ICC
+ // for embedded ICC in TIFF
+#define PropertyTagGamma 0x0301
+#define PropertyTagICCProfileDescriptor 0x0302
+#define PropertyTagSRGBRenderingIntent 0x0303
+
+#define PropertyTagImageTitle 0x0320
+#define PropertyTagCopyright 0x8298
+
+// Extra TAGs (Like Adobe Image Information tags etc.)
+
+#define PropertyTagResolutionXUnit 0x5001
+#define PropertyTagResolutionYUnit 0x5002
+#define PropertyTagResolutionXLengthUnit 0x5003
+#define PropertyTagResolutionYLengthUnit 0x5004
+#define PropertyTagPrintFlags 0x5005
+#define PropertyTagPrintFlagsVersion 0x5006
+#define PropertyTagPrintFlagsCrop 0x5007
+#define PropertyTagPrintFlagsBleedWidth 0x5008
+#define PropertyTagPrintFlagsBleedWidthScale 0x5009
+#define PropertyTagHalftoneLPI 0x500A
+#define PropertyTagHalftoneLPIUnit 0x500B
+#define PropertyTagHalftoneDegree 0x500C
+#define PropertyTagHalftoneShape 0x500D
+#define PropertyTagHalftoneMisc 0x500E
+#define PropertyTagHalftoneScreen 0x500F
+#define PropertyTagJPEGQuality 0x5010
+#define PropertyTagGridSize 0x5011
+#define PropertyTagThumbnailFormat 0x5012 // 1 = JPEG, 0 = RAW RGB
+#define PropertyTagThumbnailWidth 0x5013
+#define PropertyTagThumbnailHeight 0x5014
+#define PropertyTagThumbnailColorDepth 0x5015
+#define PropertyTagThumbnailPlanes 0x5016
+#define PropertyTagThumbnailRawBytes 0x5017
+#define PropertyTagThumbnailSize 0x5018
+#define PropertyTagThumbnailCompressedSize 0x5019
+#define PropertyTagColorTransferFunction 0x501A
+#define PropertyTagThumbnailData 0x501B// RAW thumbnail bits in
+ // JPEG format or RGB format
+ // depends on
+ // PropertyTagThumbnailFormat
+
+// Thumbnail related TAGs
+
+#define PropertyTagThumbnailImageWidth 0x5020 // Thumbnail width
+#define PropertyTagThumbnailImageHeight 0x5021 // Thumbnail height
+#define PropertyTagThumbnailBitsPerSample 0x5022 // Number of bits per
+ // component
+#define PropertyTagThumbnailCompression 0x5023 // Compression Scheme
+#define PropertyTagThumbnailPhotometricInterp 0x5024 // Pixel composition
+#define PropertyTagThumbnailImageDescription 0x5025 // Image Tile
+#define PropertyTagThumbnailEquipMake 0x5026 // Manufacturer of Image
+ // Input equipment
+#define PropertyTagThumbnailEquipModel 0x5027 // Model of Image input
+ // equipment
+#define PropertyTagThumbnailStripOffsets 0x5028 // Image data location
+#define PropertyTagThumbnailOrientation 0x5029 // Orientation of image
+#define PropertyTagThumbnailSamplesPerPixel 0x502A // Number of components
+#define PropertyTagThumbnailRowsPerStrip 0x502B // Number of rows per strip
+#define PropertyTagThumbnailStripBytesCount 0x502C // Bytes per compressed
+ // strip
+#define PropertyTagThumbnailResolutionX 0x502D // Resolution in width
+ // direction
+#define PropertyTagThumbnailResolutionY 0x502E // Resolution in height
+ // direction
+#define PropertyTagThumbnailPlanarConfig 0x502F // Image data arrangement
+#define PropertyTagThumbnailResolutionUnit 0x5030 // Unit of X and Y
+ // Resolution
+#define PropertyTagThumbnailTransferFunction 0x5031 // Transfer function
+#define PropertyTagThumbnailSoftwareUsed 0x5032 // Software used
+#define PropertyTagThumbnailDateTime 0x5033 // File change date and
+ // time
+#define PropertyTagThumbnailArtist 0x5034 // Person who created the
+ // image
+#define PropertyTagThumbnailWhitePoint 0x5035 // White point chromaticity
+#define PropertyTagThumbnailPrimaryChromaticities 0x5036
+ // Chromaticities of
+ // primaries
+#define PropertyTagThumbnailYCbCrCoefficients 0x5037 // Color space transforma-
+ // tion coefficients
+#define PropertyTagThumbnailYCbCrSubsampling 0x5038 // Subsampling ratio of Y
+ // to C
+#define PropertyTagThumbnailYCbCrPositioning 0x5039 // Y and C position
+#define PropertyTagThumbnailRefBlackWhite 0x503A // Pair of black and white
+ // reference values
+#define PropertyTagThumbnailCopyRight 0x503B // CopyRight holder
+
+#define PropertyTagLuminanceTable 0x5090
+#define PropertyTagChrominanceTable 0x5091
+
+#define PropertyTagFrameDelay 0x5100
+#define PropertyTagLoopCount 0x5101
+
+#define PropertyTagPixelUnit 0x5110 // Unit specifier for pixel/unit
+#define PropertyTagPixelPerUnitX 0x5111 // Pixels per unit in X
+#define PropertyTagPixelPerUnitY 0x5112 // Pixels per unit in Y
+#define PropertyTagPaletteHistogram 0x5113 // Palette histogram
+
+// EXIF specific tag
+
+#define PropertyTagExifExposureTime 0x829A
+#define PropertyTagExifFNumber 0x829D
+
+#define PropertyTagExifExposureProg 0x8822
+#define PropertyTagExifSpectralSense 0x8824
+#define PropertyTagExifISOSpeed 0x8827
+#define PropertyTagExifOECF 0x8828
+
+#define PropertyTagExifVer 0x9000
+#define PropertyTagExifDTOrig 0x9003 // Date & time of original
+#define PropertyTagExifDTDigitized 0x9004 // Date & time of digital data generation
+
+#define PropertyTagExifCompConfig 0x9101
+#define PropertyTagExifCompBPP 0x9102
+
+#define PropertyTagExifShutterSpeed 0x9201
+#define PropertyTagExifAperture 0x9202
+#define PropertyTagExifBrightness 0x9203
+#define PropertyTagExifExposureBias 0x9204
+#define PropertyTagExifMaxAperture 0x9205
+#define PropertyTagExifSubjectDist 0x9206
+#define PropertyTagExifMeteringMode 0x9207
+#define PropertyTagExifLightSource 0x9208
+#define PropertyTagExifFlash 0x9209
+#define PropertyTagExifFocalLength 0x920A
+#define PropertyTagExifMakerNote 0x927C
+#define PropertyTagExifUserComment 0x9286
+#define PropertyTagExifDTSubsec 0x9290 // Date & Time subseconds
+#define PropertyTagExifDTOrigSS 0x9291 // Date & Time original subseconds
+#define PropertyTagExifDTDigSS 0x9292 // Date & TIme digitized subseconds
+
+#define PropertyTagExifFPXVer 0xA000
+#define PropertyTagExifColorSpace 0xA001
+#define PropertyTagExifPixXDim 0xA002
+#define PropertyTagExifPixYDim 0xA003
+#define PropertyTagExifRelatedWav 0xA004 // related sound file
+#define PropertyTagExifInterop 0xA005
+#define PropertyTagExifFlashEnergy 0xA20B
+#define PropertyTagExifSpatialFR 0xA20C // Spatial Frequency Response
+#define PropertyTagExifFocalXRes 0xA20E // Focal Plane X Resolution
+#define PropertyTagExifFocalYRes 0xA20F // Focal Plane Y Resolution
+#define PropertyTagExifFocalResUnit 0xA210 // Focal Plane Resolution Unit
+#define PropertyTagExifSubjectLoc 0xA214
+#define PropertyTagExifExposureIndex 0xA215
+#define PropertyTagExifSensingMethod 0xA217
+#define PropertyTagExifFileSource 0xA300
+#define PropertyTagExifSceneType 0xA301
+#define PropertyTagExifCfaPattern 0xA302
+
+#define PropertyTagGpsVer 0x0000
+#define PropertyTagGpsLatitudeRef 0x0001
+#define PropertyTagGpsLatitude 0x0002
+#define PropertyTagGpsLongitudeRef 0x0003
+#define PropertyTagGpsLongitude 0x0004
+#define PropertyTagGpsAltitudeRef 0x0005
+#define PropertyTagGpsAltitude 0x0006
+#define PropertyTagGpsGpsTime 0x0007
+#define PropertyTagGpsGpsSatellites 0x0008
+#define PropertyTagGpsGpsStatus 0x0009
+#define PropertyTagGpsGpsMeasureMode 0x00A
+#define PropertyTagGpsGpsDop 0x000B // Measurement precision
+#define PropertyTagGpsSpeedRef 0x000C
+#define PropertyTagGpsSpeed 0x000D
+#define PropertyTagGpsTrackRef 0x000E
+#define PropertyTagGpsTrack 0x000F
+#define PropertyTagGpsImgDirRef 0x0010
+#define PropertyTagGpsImgDir 0x0011
+#define PropertyTagGpsMapDatum 0x0012
+#define PropertyTagGpsDestLatRef 0x0013
+#define PropertyTagGpsDestLat 0x0014
+#define PropertyTagGpsDestLongRef 0x0015
+#define PropertyTagGpsDestLong 0x0016
+#define PropertyTagGpsDestBearRef 0x0017
+#define PropertyTagGpsDestBear 0x0018
+#define PropertyTagGpsDestDistRef 0x0019
+#define PropertyTagGpsDestDist 0x001A
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusLineCaps.h b/core/src/fxge/Microsoft SDK/include/GdiPlusLineCaps.h
index e8a2951f43..5ac880f59a 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusLineCaps.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusLineCaps.h
@@ -1,253 +1,253 @@
-/**************************************************************************\
-*
-* Copyright (c) 2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusLineCaps.h
-*
-* Abstract:
-*
-* APIs for Custom Line Caps
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSLINECAPS_H
-#define _GDIPLUSLINECAPS_H
-
-inline
-CustomLineCap::CustomLineCap(
- IN const GraphicsPath* fillPath,
- IN const GraphicsPath* strokePath,
- IN LineCap baseCap,
- IN REAL baseInset
- )
-{
- nativeCap = NULL;
- GpPath* nativeFillPath = NULL;
- GpPath* nativeStrokePath = NULL;
-
- if(fillPath)
- nativeFillPath = fillPath->nativePath;
- if(strokePath)
- nativeStrokePath = strokePath->nativePath;
-
- lastResult = DllExports::GdipCreateCustomLineCap(
- nativeFillPath, nativeStrokePath,
- baseCap, baseInset, &nativeCap);
-}
-
-inline
-CustomLineCap::CustomLineCap()
-{
- // This is used for default constructor for subclasses.
- // So don't create a nativeCap.
-
- nativeCap = NULL;
- lastResult = Ok;
-}
-
-inline
-CustomLineCap::~CustomLineCap()
-{
- DllExports::GdipDeleteCustomLineCap(nativeCap);
-}
-
-inline Status
-CustomLineCap::SetStrokeCaps(
- IN LineCap startCap,
- IN LineCap endCap)
-{
- return SetStatus(DllExports::GdipSetCustomLineCapStrokeCaps(nativeCap,
- startCap, endCap));
-}
-
-inline Status
-CustomLineCap::GetStrokeCaps(
- OUT LineCap* startCap,
- OUT LineCap* endCap) const
-{
- return SetStatus(DllExports::GdipGetCustomLineCapStrokeCaps(nativeCap,
- startCap, endCap));
-}
-
-inline Status
-CustomLineCap::SetStrokeJoin(
- IN LineJoin lineJoin)
-{
- return SetStatus(DllExports::GdipSetCustomLineCapStrokeJoin(nativeCap, lineJoin));
-}
-
-inline LineJoin
-CustomLineCap::GetStrokeJoin() const
-{
- LineJoin lineJoin;
-
- SetStatus(DllExports::GdipGetCustomLineCapStrokeJoin(nativeCap, &lineJoin));
-
- return lineJoin;
-}
-
-inline Status
-CustomLineCap::SetBaseCap(IN LineCap baseCap)
-{
- return SetStatus(DllExports::GdipSetCustomLineCapBaseCap(nativeCap, baseCap));
-}
-
-inline LineCap
-CustomLineCap::GetBaseCap() const
-{
- LineCap baseCap;
- SetStatus(DllExports::GdipGetCustomLineCapBaseCap(nativeCap, &baseCap));
-
- return baseCap;
-}
-
-inline Status
-CustomLineCap::SetBaseInset(IN REAL inset)
-{
- return SetStatus(DllExports::GdipSetCustomLineCapBaseInset(nativeCap, inset));
-}
-
-inline REAL
-CustomLineCap::GetBaseInset() const
-{
- REAL inset;
- SetStatus(DllExports::GdipGetCustomLineCapBaseInset(nativeCap, &inset));
-
- return inset;
-}
-
-
-inline Status
-CustomLineCap::SetWidthScale(IN REAL widthScale)
-{
- return SetStatus(DllExports::GdipSetCustomLineCapWidthScale(nativeCap, widthScale));
-}
-
-inline REAL
-CustomLineCap::GetWidthScale() const
-{
- REAL widthScale;
- SetStatus(DllExports::GdipGetCustomLineCapWidthScale(nativeCap, &widthScale));
-
- return widthScale;
-}
-
-inline CustomLineCap*
-CustomLineCap::Clone() const
-{
- GpCustomLineCap *newNativeLineCap = NULL;
-
- SetStatus(DllExports::GdipCloneCustomLineCap(nativeCap, &newNativeLineCap));
-
- if (lastResult == Ok)
- {
- CustomLineCap *newLineCap = new CustomLineCap(newNativeLineCap, lastResult);
- if (newLineCap == NULL)
- {
- SetStatus(DllExports::GdipDeleteCustomLineCap(newNativeLineCap));
- }
-
- return newLineCap;
- }
-
- return NULL;
-}
-
-class AdjustableArrowCap : public CustomLineCap
-{
-public:
-
- AdjustableArrowCap(
- IN REAL height,
- IN REAL width,
- IN BOOL isFilled = TRUE
- )
- {
- GpAdjustableArrowCap* cap = NULL;
-
- lastResult = DllExports::GdipCreateAdjustableArrowCap(
- height, width, isFilled, &cap);
- SetNativeCap(cap);
- }
-
- Status SetHeight(IN REAL height)
- {
- GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
- return SetStatus(DllExports::GdipSetAdjustableArrowCapHeight(
- cap, height));
- }
-
- REAL GetHeight() const
- {
- GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
- REAL height;
- SetStatus(DllExports::GdipGetAdjustableArrowCapHeight(
- cap, &height));
-
- return height;
- }
-
- Status SetWidth(IN REAL width)
- {
- GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
- return SetStatus(DllExports::GdipSetAdjustableArrowCapWidth(
- cap, width));
- }
-
- REAL GetWidth() const
- {
- GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
- REAL width;
- SetStatus(DllExports::GdipGetAdjustableArrowCapWidth(
- cap, &width));
-
- return width;
- }
-
- Status SetMiddleInset(IN REAL middleInset)
- {
- GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
- return SetStatus(DllExports::GdipSetAdjustableArrowCapMiddleInset(
- cap, middleInset));
- }
-
- REAL GetMiddleInset() const
- {
- GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
- REAL middleInset;
- SetStatus(DllExports::GdipGetAdjustableArrowCapMiddleInset(
- cap, &middleInset));
-
- return middleInset;
- }
-
- Status SetFillState(IN BOOL isFilled)
- {
- GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
- return SetStatus(DllExports::GdipSetAdjustableArrowCapFillState(
- cap, isFilled));
- }
-
- BOOL IsFilled() const
- {
- GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
- BOOL isFilled;
- SetStatus(DllExports::GdipGetAdjustableArrowCapFillState(
- cap, &isFilled));
-
- return isFilled;
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- AdjustableArrowCap(const AdjustableArrowCap &);
- AdjustableArrowCap& operator=(const AdjustableArrowCap &);
-
-#endif
-
-};
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusLineCaps.h
+*
+* Abstract:
+*
+* APIs for Custom Line Caps
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSLINECAPS_H
+#define _GDIPLUSLINECAPS_H
+
+inline
+CustomLineCap::CustomLineCap(
+ IN const GraphicsPath* fillPath,
+ IN const GraphicsPath* strokePath,
+ IN LineCap baseCap,
+ IN REAL baseInset
+ )
+{
+ nativeCap = NULL;
+ GpPath* nativeFillPath = NULL;
+ GpPath* nativeStrokePath = NULL;
+
+ if(fillPath)
+ nativeFillPath = fillPath->nativePath;
+ if(strokePath)
+ nativeStrokePath = strokePath->nativePath;
+
+ lastResult = DllExports::GdipCreateCustomLineCap(
+ nativeFillPath, nativeStrokePath,
+ baseCap, baseInset, &nativeCap);
+}
+
+inline
+CustomLineCap::CustomLineCap()
+{
+ // This is used for default constructor for subclasses.
+ // So don't create a nativeCap.
+
+ nativeCap = NULL;
+ lastResult = Ok;
+}
+
+inline
+CustomLineCap::~CustomLineCap()
+{
+ DllExports::GdipDeleteCustomLineCap(nativeCap);
+}
+
+inline Status
+CustomLineCap::SetStrokeCaps(
+ IN LineCap startCap,
+ IN LineCap endCap)
+{
+ return SetStatus(DllExports::GdipSetCustomLineCapStrokeCaps(nativeCap,
+ startCap, endCap));
+}
+
+inline Status
+CustomLineCap::GetStrokeCaps(
+ OUT LineCap* startCap,
+ OUT LineCap* endCap) const
+{
+ return SetStatus(DllExports::GdipGetCustomLineCapStrokeCaps(nativeCap,
+ startCap, endCap));
+}
+
+inline Status
+CustomLineCap::SetStrokeJoin(
+ IN LineJoin lineJoin)
+{
+ return SetStatus(DllExports::GdipSetCustomLineCapStrokeJoin(nativeCap, lineJoin));
+}
+
+inline LineJoin
+CustomLineCap::GetStrokeJoin() const
+{
+ LineJoin lineJoin;
+
+ SetStatus(DllExports::GdipGetCustomLineCapStrokeJoin(nativeCap, &lineJoin));
+
+ return lineJoin;
+}
+
+inline Status
+CustomLineCap::SetBaseCap(IN LineCap baseCap)
+{
+ return SetStatus(DllExports::GdipSetCustomLineCapBaseCap(nativeCap, baseCap));
+}
+
+inline LineCap
+CustomLineCap::GetBaseCap() const
+{
+ LineCap baseCap;
+ SetStatus(DllExports::GdipGetCustomLineCapBaseCap(nativeCap, &baseCap));
+
+ return baseCap;
+}
+
+inline Status
+CustomLineCap::SetBaseInset(IN REAL inset)
+{
+ return SetStatus(DllExports::GdipSetCustomLineCapBaseInset(nativeCap, inset));
+}
+
+inline REAL
+CustomLineCap::GetBaseInset() const
+{
+ REAL inset;
+ SetStatus(DllExports::GdipGetCustomLineCapBaseInset(nativeCap, &inset));
+
+ return inset;
+}
+
+
+inline Status
+CustomLineCap::SetWidthScale(IN REAL widthScale)
+{
+ return SetStatus(DllExports::GdipSetCustomLineCapWidthScale(nativeCap, widthScale));
+}
+
+inline REAL
+CustomLineCap::GetWidthScale() const
+{
+ REAL widthScale;
+ SetStatus(DllExports::GdipGetCustomLineCapWidthScale(nativeCap, &widthScale));
+
+ return widthScale;
+}
+
+inline CustomLineCap*
+CustomLineCap::Clone() const
+{
+ GpCustomLineCap *newNativeLineCap = NULL;
+
+ SetStatus(DllExports::GdipCloneCustomLineCap(nativeCap, &newNativeLineCap));
+
+ if (lastResult == Ok)
+ {
+ CustomLineCap *newLineCap = new CustomLineCap(newNativeLineCap, lastResult);
+ if (newLineCap == NULL)
+ {
+ SetStatus(DllExports::GdipDeleteCustomLineCap(newNativeLineCap));
+ }
+
+ return newLineCap;
+ }
+
+ return NULL;
+}
+
+class AdjustableArrowCap : public CustomLineCap
+{
+public:
+
+ AdjustableArrowCap(
+ IN REAL height,
+ IN REAL width,
+ IN BOOL isFilled = TRUE
+ )
+ {
+ GpAdjustableArrowCap* cap = NULL;
+
+ lastResult = DllExports::GdipCreateAdjustableArrowCap(
+ height, width, isFilled, &cap);
+ SetNativeCap(cap);
+ }
+
+ Status SetHeight(IN REAL height)
+ {
+ GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
+ return SetStatus(DllExports::GdipSetAdjustableArrowCapHeight(
+ cap, height));
+ }
+
+ REAL GetHeight() const
+ {
+ GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
+ REAL height;
+ SetStatus(DllExports::GdipGetAdjustableArrowCapHeight(
+ cap, &height));
+
+ return height;
+ }
+
+ Status SetWidth(IN REAL width)
+ {
+ GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
+ return SetStatus(DllExports::GdipSetAdjustableArrowCapWidth(
+ cap, width));
+ }
+
+ REAL GetWidth() const
+ {
+ GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
+ REAL width;
+ SetStatus(DllExports::GdipGetAdjustableArrowCapWidth(
+ cap, &width));
+
+ return width;
+ }
+
+ Status SetMiddleInset(IN REAL middleInset)
+ {
+ GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
+ return SetStatus(DllExports::GdipSetAdjustableArrowCapMiddleInset(
+ cap, middleInset));
+ }
+
+ REAL GetMiddleInset() const
+ {
+ GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
+ REAL middleInset;
+ SetStatus(DllExports::GdipGetAdjustableArrowCapMiddleInset(
+ cap, &middleInset));
+
+ return middleInset;
+ }
+
+ Status SetFillState(IN BOOL isFilled)
+ {
+ GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
+ return SetStatus(DllExports::GdipSetAdjustableArrowCapFillState(
+ cap, isFilled));
+ }
+
+ BOOL IsFilled() const
+ {
+ GpAdjustableArrowCap* cap = (GpAdjustableArrowCap*) nativeCap;
+ BOOL isFilled;
+ SetStatus(DllExports::GdipGetAdjustableArrowCapFillState(
+ cap, &isFilled));
+
+ return isFilled;
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ AdjustableArrowCap(const AdjustableArrowCap &);
+ AdjustableArrowCap& operator=(const AdjustableArrowCap &);
+
+#endif
+
+};
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusMatrix.h b/core/src/fxge/Microsoft SDK/include/GdiPlusMatrix.h
index 7fa3df8cd1..1338d8c1ac 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusMatrix.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusMatrix.h
@@ -1,309 +1,309 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusMatrix.h
-*
-* Abstract:
-*
-* GDI+ Matrix class
-*
-\**************************************************************************/
-
-class Matrix : public GdiplusBase
-{
-public:
- friend class Graphics;
- friend class GraphicsPath;
- friend class TextureBrush;
- friend class LinearGradientBrush;
- friend class PathGradientBrush;
- friend class Pen;
- friend class Region;
-
- // Default constructor - set to identity matrix
-
- Matrix()
- {
- GpMatrix *matrix = NULL;
-
- lastResult = DllExports::GdipCreateMatrix(&matrix);
-
- SetNativeMatrix(matrix);
- }
-
- Matrix(IN REAL m11,
- IN REAL m12,
- IN REAL m21,
- IN REAL m22,
- IN REAL dx,
- IN REAL dy)
- {
- GpMatrix *matrix = NULL;
-
- lastResult = DllExports::GdipCreateMatrix2(m11, m12, m21, m22,
- dx, dy, &matrix);
-
- SetNativeMatrix(matrix);
- }
-
- Matrix(IN const RectF& rect,
- IN const PointF* dstplg)
- {
- GpMatrix *matrix = NULL;
-
- lastResult = DllExports::GdipCreateMatrix3(&rect,
- dstplg,
- &matrix);
-
- SetNativeMatrix(matrix);
- }
-
- Matrix(IN const Rect& rect,
- IN const Point* dstplg)
- {
- GpMatrix *matrix = NULL;
-
- lastResult = DllExports::GdipCreateMatrix3I(&rect,
- dstplg,
- &matrix);
-
- SetNativeMatrix(matrix);
- }
-
- ~Matrix()
- {
- DllExports::GdipDeleteMatrix(nativeMatrix);
- }
-
- Matrix *Clone() const
- {
- GpMatrix *cloneMatrix = NULL;
-
- SetStatus(DllExports::GdipCloneMatrix(nativeMatrix,
- &cloneMatrix));
-
- if (lastResult != Ok)
- return NULL;
-
- return new Matrix(cloneMatrix);
- }
-
- Status GetElements(OUT REAL *m) const
- {
- return SetStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m));
- }
-
- Status SetElements(IN REAL m11,
- IN REAL m12,
- IN REAL m21,
- IN REAL m22,
- IN REAL dx,
- IN REAL dy)
- {
- return SetStatus(DllExports::GdipSetMatrixElements(nativeMatrix,
- m11, m12, m21, m22, dx, dy));
- }
-
- REAL OffsetX() const
- {
- REAL elements[6];
-
- if (GetElements(&elements[0]) == Ok)
- return elements[4];
- else
- return 0.0f;
- }
-
- REAL OffsetY() const
- {
- REAL elements[6];
-
- if (GetElements(&elements[0]) == Ok)
- return elements[5];
- else
- return 0.0f;
- }
-
- Status Reset()
- {
- // set identity matrix elements
- return SetStatus(DllExports::GdipSetMatrixElements(nativeMatrix,
- 1.0, 0.0, 0.0, 1.0, 0.0, 0.0));
- }
-
- Status Multiply(IN const Matrix *matrix,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipMultiplyMatrix(nativeMatrix,
- matrix->nativeMatrix,
- order));
- }
-
- Status Translate(IN REAL offsetX,
- IN REAL offsetY,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, offsetX, offsetY, order));
- }
-
- Status Scale(IN REAL scaleX,
- IN REAL scaleY,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipScaleMatrix(nativeMatrix, scaleX, scaleY, order));
- }
-
- Status Rotate(IN REAL angle,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
- }
-
- Status RotateAt(IN REAL angle,
- IN const PointF& center,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- if(order == MatrixOrderPrepend)
- {
- SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order));
- SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
- return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, - center.X, - center.Y, order));
- }
- else
- {
- SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, - center.X, - center.Y, order));
- SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
- return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order));
- }
- }
-
- Status Shear(IN REAL shearX,
- IN REAL shearY,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipShearMatrix(nativeMatrix, shearX, shearY, order));
- }
-
- Status Invert()
- {
- return SetStatus(DllExports::GdipInvertMatrix(nativeMatrix));
- }
-
- // float version
- Status TransformPoints(IN OUT PointF* pts,
- IN INT count = 1) const
- {
- return SetStatus(DllExports::GdipTransformMatrixPoints(nativeMatrix, pts, count));
- }
-
- Status TransformPoints(IN OUT Point* pts,
- IN INT count = 1) const
- {
- return SetStatus(DllExports::GdipTransformMatrixPointsI(nativeMatrix,
- pts,
- count));
- }
-
- Status TransformVectors(IN OUT PointF* pts,
- IN INT count = 1) const
- {
- return SetStatus(DllExports::GdipVectorTransformMatrixPoints(nativeMatrix, pts, count));
- }
-
- Status TransformVectors(IN OUT Point* pts,
- IN INT count = 1) const
- {
- return SetStatus(DllExports::GdipVectorTransformMatrixPointsI(nativeMatrix,
- pts,
- count));
- }
-
- BOOL IsInvertible() const
- {
- BOOL result = FALSE;
-
- SetStatus(DllExports::GdipIsMatrixInvertible(nativeMatrix, &result));
-
- return result;
- }
-
- BOOL IsIdentity() const
- {
- BOOL result = FALSE;
-
- SetStatus(DllExports::GdipIsMatrixIdentity(nativeMatrix, &result));
-
- return result;
- }
-
- BOOL Equals(IN const Matrix *matrix) const
- {
- BOOL result = FALSE;
-
- SetStatus(DllExports::GdipIsMatrixEqual(nativeMatrix,
- matrix->nativeMatrix, &result));
-
- return result;
- }
-
- Status GetLastStatus() const
- {
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
- }
-
-protected:
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- Matrix(const Matrix &);
- Matrix& operator=(const Matrix &);
-protected:
-
-#else
-
- Matrix(const Matrix& matrix)
- {
- matrix;
- SetStatus(NotImplemented);
- SetNativeMatrix(NULL);
- }
-
- Matrix& operator=(const Matrix& matrix)
- {
- matrix;
- SetStatus(NotImplemented);
- return *this;
- }
-
-#endif
-
- Matrix(GpMatrix *nativeMatrix)
- {
- lastResult = Ok;
- SetNativeMatrix(nativeMatrix);
- }
-
- VOID SetNativeMatrix(GpMatrix *nativeMatrix)
- {
- this->nativeMatrix = nativeMatrix;
- }
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
-protected:
- GpMatrix *nativeMatrix;
- mutable Status lastResult;
-};
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusMatrix.h
+*
+* Abstract:
+*
+* GDI+ Matrix class
+*
+\**************************************************************************/
+
+class Matrix : public GdiplusBase
+{
+public:
+ friend class Graphics;
+ friend class GraphicsPath;
+ friend class TextureBrush;
+ friend class LinearGradientBrush;
+ friend class PathGradientBrush;
+ friend class Pen;
+ friend class Region;
+
+ // Default constructor - set to identity matrix
+
+ Matrix()
+ {
+ GpMatrix *matrix = NULL;
+
+ lastResult = DllExports::GdipCreateMatrix(&matrix);
+
+ SetNativeMatrix(matrix);
+ }
+
+ Matrix(IN REAL m11,
+ IN REAL m12,
+ IN REAL m21,
+ IN REAL m22,
+ IN REAL dx,
+ IN REAL dy)
+ {
+ GpMatrix *matrix = NULL;
+
+ lastResult = DllExports::GdipCreateMatrix2(m11, m12, m21, m22,
+ dx, dy, &matrix);
+
+ SetNativeMatrix(matrix);
+ }
+
+ Matrix(IN const RectF& rect,
+ IN const PointF* dstplg)
+ {
+ GpMatrix *matrix = NULL;
+
+ lastResult = DllExports::GdipCreateMatrix3(&rect,
+ dstplg,
+ &matrix);
+
+ SetNativeMatrix(matrix);
+ }
+
+ Matrix(IN const Rect& rect,
+ IN const Point* dstplg)
+ {
+ GpMatrix *matrix = NULL;
+
+ lastResult = DllExports::GdipCreateMatrix3I(&rect,
+ dstplg,
+ &matrix);
+
+ SetNativeMatrix(matrix);
+ }
+
+ ~Matrix()
+ {
+ DllExports::GdipDeleteMatrix(nativeMatrix);
+ }
+
+ Matrix *Clone() const
+ {
+ GpMatrix *cloneMatrix = NULL;
+
+ SetStatus(DllExports::GdipCloneMatrix(nativeMatrix,
+ &cloneMatrix));
+
+ if (lastResult != Ok)
+ return NULL;
+
+ return new Matrix(cloneMatrix);
+ }
+
+ Status GetElements(OUT REAL *m) const
+ {
+ return SetStatus(DllExports::GdipGetMatrixElements(nativeMatrix, m));
+ }
+
+ Status SetElements(IN REAL m11,
+ IN REAL m12,
+ IN REAL m21,
+ IN REAL m22,
+ IN REAL dx,
+ IN REAL dy)
+ {
+ return SetStatus(DllExports::GdipSetMatrixElements(nativeMatrix,
+ m11, m12, m21, m22, dx, dy));
+ }
+
+ REAL OffsetX() const
+ {
+ REAL elements[6];
+
+ if (GetElements(&elements[0]) == Ok)
+ return elements[4];
+ else
+ return 0.0f;
+ }
+
+ REAL OffsetY() const
+ {
+ REAL elements[6];
+
+ if (GetElements(&elements[0]) == Ok)
+ return elements[5];
+ else
+ return 0.0f;
+ }
+
+ Status Reset()
+ {
+ // set identity matrix elements
+ return SetStatus(DllExports::GdipSetMatrixElements(nativeMatrix,
+ 1.0, 0.0, 0.0, 1.0, 0.0, 0.0));
+ }
+
+ Status Multiply(IN const Matrix *matrix,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipMultiplyMatrix(nativeMatrix,
+ matrix->nativeMatrix,
+ order));
+ }
+
+ Status Translate(IN REAL offsetX,
+ IN REAL offsetY,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, offsetX, offsetY, order));
+ }
+
+ Status Scale(IN REAL scaleX,
+ IN REAL scaleY,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipScaleMatrix(nativeMatrix, scaleX, scaleY, order));
+ }
+
+ Status Rotate(IN REAL angle,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
+ }
+
+ Status RotateAt(IN REAL angle,
+ IN const PointF& center,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ if(order == MatrixOrderPrepend)
+ {
+ SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order));
+ SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
+ return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, - center.X, - center.Y, order));
+ }
+ else
+ {
+ SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, - center.X, - center.Y, order));
+ SetStatus(DllExports::GdipRotateMatrix(nativeMatrix, angle, order));
+ return SetStatus(DllExports::GdipTranslateMatrix(nativeMatrix, center.X, center.Y, order));
+ }
+ }
+
+ Status Shear(IN REAL shearX,
+ IN REAL shearY,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipShearMatrix(nativeMatrix, shearX, shearY, order));
+ }
+
+ Status Invert()
+ {
+ return SetStatus(DllExports::GdipInvertMatrix(nativeMatrix));
+ }
+
+ // float version
+ Status TransformPoints(IN OUT PointF* pts,
+ IN INT count = 1) const
+ {
+ return SetStatus(DllExports::GdipTransformMatrixPoints(nativeMatrix, pts, count));
+ }
+
+ Status TransformPoints(IN OUT Point* pts,
+ IN INT count = 1) const
+ {
+ return SetStatus(DllExports::GdipTransformMatrixPointsI(nativeMatrix,
+ pts,
+ count));
+ }
+
+ Status TransformVectors(IN OUT PointF* pts,
+ IN INT count = 1) const
+ {
+ return SetStatus(DllExports::GdipVectorTransformMatrixPoints(nativeMatrix, pts, count));
+ }
+
+ Status TransformVectors(IN OUT Point* pts,
+ IN INT count = 1) const
+ {
+ return SetStatus(DllExports::GdipVectorTransformMatrixPointsI(nativeMatrix,
+ pts,
+ count));
+ }
+
+ BOOL IsInvertible() const
+ {
+ BOOL result = FALSE;
+
+ SetStatus(DllExports::GdipIsMatrixInvertible(nativeMatrix, &result));
+
+ return result;
+ }
+
+ BOOL IsIdentity() const
+ {
+ BOOL result = FALSE;
+
+ SetStatus(DllExports::GdipIsMatrixIdentity(nativeMatrix, &result));
+
+ return result;
+ }
+
+ BOOL Equals(IN const Matrix *matrix) const
+ {
+ BOOL result = FALSE;
+
+ SetStatus(DllExports::GdipIsMatrixEqual(nativeMatrix,
+ matrix->nativeMatrix, &result));
+
+ return result;
+ }
+
+ Status GetLastStatus() const
+ {
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+ }
+
+protected:
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ Matrix(const Matrix &);
+ Matrix& operator=(const Matrix &);
+protected:
+
+#else
+
+ Matrix(const Matrix& matrix)
+ {
+ matrix;
+ SetStatus(NotImplemented);
+ SetNativeMatrix(NULL);
+ }
+
+ Matrix& operator=(const Matrix& matrix)
+ {
+ matrix;
+ SetStatus(NotImplemented);
+ return *this;
+ }
+
+#endif
+
+ Matrix(GpMatrix *nativeMatrix)
+ {
+ lastResult = Ok;
+ SetNativeMatrix(nativeMatrix);
+ }
+
+ VOID SetNativeMatrix(GpMatrix *nativeMatrix)
+ {
+ this->nativeMatrix = nativeMatrix;
+ }
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+protected:
+ GpMatrix *nativeMatrix;
+ mutable Status lastResult;
+};
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusMem.h b/core/src/fxge/Microsoft SDK/include/GdiPlusMem.h
index 5f92c1e141..a0e0e44f37 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusMem.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusMem.h
@@ -1,49 +1,49 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusMem.h
-*
-* Abstract:
-*
-* Flat GDI+ Memory Allocators - header file
-*
-\**************************************************************************/
-
-// TODO: this file style needs to be made internally consistent with the way
-// it handles breaking the long argument lists across multiple lines
-
-#ifndef _GDIPLUSMEM_H
-#define _GDIPLUSMEM_H
-
-#define WINGDIPAPI __stdcall
-
-// currently, only C++ wrapper API's force const.
-
-#ifdef _GDIPLUS_H
-#define GDIPCONST const
-#else
-#define GDIPCONST
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//----------------------------------------------------------------------------
-// Memory Allocation APIs
-//----------------------------------------------------------------------------
-
-void* WINGDIPAPI
-GdipAlloc(size_t size);
-
-void WINGDIPAPI
-GdipFree(void* ptr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // !_GDIPLUSMEM_H
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusMem.h
+*
+* Abstract:
+*
+* Flat GDI+ Memory Allocators - header file
+*
+\**************************************************************************/
+
+// TODO: this file style needs to be made internally consistent with the way
+// it handles breaking the long argument lists across multiple lines
+
+#ifndef _GDIPLUSMEM_H
+#define _GDIPLUSMEM_H
+
+#define WINGDIPAPI __stdcall
+
+// currently, only C++ wrapper API's force const.
+
+#ifdef _GDIPLUS_H
+#define GDIPCONST const
+#else
+#define GDIPCONST
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//----------------------------------------------------------------------------
+// Memory Allocation APIs
+//----------------------------------------------------------------------------
+
+void* WINGDIPAPI
+GdipAlloc(size_t size);
+
+void WINGDIPAPI
+GdipFree(void* ptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !_GDIPLUSMEM_H
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusMetaFile.h b/core/src/fxge/Microsoft SDK/include/GdiPlusMetaFile.h
index 3d07dd64d3..f7e0d91aaa 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusMetaFile.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusMetaFile.h
@@ -1,374 +1,374 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusMetafile.h
-*
-* Abstract:
-*
-* Metafile related declarations
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSMETAFILE_H
-#define _GDIPLUSMETAFILE_H
-
-class Metafile : public Image
-{
-public:
- friend class Image;
-
- // Read a metafile
- Metafile()
- {
- SetNativeImage(NULL);
- lastResult = Ok;
- }
-
- // Playback a metafile from a HMETAFILE
- // If deleteWmf is TRUE, then when the metafile is deleted,
- // the hWmf will also be deleted. Otherwise, it won't be.
- Metafile(IN HMETAFILE hWmf,
- IN const APMFileHeader * apmFileHeader,
- IN BOOL deleteWmf = FALSE)
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipCreateMetafileFromWmf(hWmf, deleteWmf, apmFileHeader, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Playback a metafile from a HENHMETAFILE
- // If deleteEmf is TRUE, then when the metafile is deleted,
- // the hEmf will also be deleted. Otherwise, it won't be.
- Metafile(IN HENHMETAFILE hEmf,
- IN BOOL deleteEmf = FALSE)
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipCreateMetafileFromEmf(hEmf, deleteEmf, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Playback a metafile from a file
- Metafile(IN const WCHAR* filename)
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipCreateMetafileFromFile(filename, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Playback a WMF metafile from a file
- Metafile(IN const WCHAR* filename,
- IN const APMFileHeader * apmFileHeader
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipCreateMetafileFromWmfFile(filename, apmFileHeader, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Playback a metafile from a stream
- Metafile(IN IStream* stream)
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipCreateMetafileFromStream(stream, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Record a metafile to memory
- Metafile(
- IN HDC referenceHdc,
- IN EmfType type = EmfTypeEmfPlusDual,
- IN const WCHAR * description = NULL
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipRecordMetafile(
- referenceHdc, type, NULL, MetafileFrameUnitGdi,
- description, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Record a metafile to memory
- Metafile(
- IN HDC referenceHdc,
- IN const RectF & frameRect,
- IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
- IN EmfType type = EmfTypeEmfPlusDual,
- IN const WCHAR * description = NULL
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipRecordMetafile(
- referenceHdc, type, &frameRect, frameUnit,
- description, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Record a metafile to memory
- Metafile(
- IN HDC referenceHdc,
- IN const Rect & frameRect,
- IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
- IN EmfType type = EmfTypeEmfPlusDual,
- IN const WCHAR * description = NULL
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipRecordMetafileI(
- referenceHdc, type, &frameRect, frameUnit,
- description, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Record a metafile to a file
- Metafile(
- IN const WCHAR* fileName,
- IN HDC referenceHdc,
- IN EmfType type = EmfTypeEmfPlusDual,
- IN const WCHAR * description = NULL
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipRecordMetafileFileName(fileName,
- referenceHdc, type, NULL, MetafileFrameUnitGdi,
- description, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Record a metafile to a file
- Metafile(
- IN const WCHAR* fileName,
- IN HDC referenceHdc,
- IN const RectF & frameRect,
- IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
- IN EmfType type = EmfTypeEmfPlusDual,
- IN const WCHAR * description = NULL
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipRecordMetafileFileName(fileName,
- referenceHdc, type, &frameRect, frameUnit,
- description, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Record a metafile to a file
- Metafile(
- IN const WCHAR* fileName,
- IN HDC referenceHdc,
- IN const Rect & frameRect,
- IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
- IN EmfType type = EmfTypeEmfPlusDual,
- IN const WCHAR * description = NULL
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipRecordMetafileFileNameI(fileName,
- referenceHdc, type, &frameRect, frameUnit,
- description, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Record a metafile to a stream
- Metafile(
- IN IStream * stream,
- IN HDC referenceHdc,
- IN EmfType type = EmfTypeEmfPlusDual,
- IN const WCHAR * description = NULL
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipRecordMetafileStream(stream,
- referenceHdc, type, NULL, MetafileFrameUnitGdi,
- description, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Record a metafile to a stream
- Metafile(
- IN IStream * stream,
- IN HDC referenceHdc,
- IN const RectF & frameRect,
- IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
- IN EmfType type = EmfTypeEmfPlusDual,
- IN const WCHAR * description = NULL
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipRecordMetafileStream(stream,
- referenceHdc, type, &frameRect, frameUnit,
- description, &metafile);
-
- SetNativeImage(metafile);
- }
-
- // Write a metafile to a stream with down-level GDI records
- Metafile(
- IN IStream * stream,
- IN HDC referenceHdc,
- IN const Rect & frameRect,
- IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
- IN EmfType type = EmfTypeEmfPlusDual,
- IN const WCHAR * description = NULL
- )
- {
- GpMetafile * metafile = NULL;
-
- lastResult = DllExports::GdipRecordMetafileStreamI(stream,
- referenceHdc, type, &frameRect, frameUnit,
- description, &metafile);
-
- SetNativeImage(metafile);
- }
-
- static Status GetMetafileHeader(
- IN HMETAFILE hWmf,
- IN const APMFileHeader * apmFileHeader,
- OUT MetafileHeader * header
- )
- {
- return DllExports::GdipGetMetafileHeaderFromWmf(hWmf, apmFileHeader, header);
- }
-
- static Status GetMetafileHeader(
- IN HENHMETAFILE hEmf,
- OUT MetafileHeader * header
- )
- {
- return DllExports::GdipGetMetafileHeaderFromEmf(hEmf, header);
- }
-
- static Status GetMetafileHeader(
- IN const WCHAR* filename,
- OUT MetafileHeader * header
- )
- {
- return DllExports::GdipGetMetafileHeaderFromFile(filename, header);
- }
-
- static Status GetMetafileHeader(
- IN IStream * stream,
- OUT MetafileHeader * header
- )
- {
- return DllExports::GdipGetMetafileHeaderFromStream(stream, header);
- }
-
- Status GetMetafileHeader(
- OUT MetafileHeader * header
- ) const
- {
- return SetStatus(DllExports::GdipGetMetafileHeaderFromMetafile(
- (GpMetafile *)nativeImage,
- header));
- }
-
- // Once this method is called, the Metafile object is in an invalid state
- // and can no longer be used. It is the responsiblity of the caller to
- // invoke DeleteEnhMetaFile to delete this hEmf.
-
- HENHMETAFILE GetHENHMETAFILE()
- {
- HENHMETAFILE hEmf;
-
- SetStatus(DllExports::GdipGetHemfFromMetafile((GpMetafile *)nativeImage, &hEmf));
-
- return hEmf;
- }
-
- // Used in conjuction with Graphics::EnumerateMetafile to play an EMF+
- // The data must be DWORD aligned if it's an EMF or EMF+. It must be
- // WORD aligned if it's a WMF.
- Status
- PlayRecord(
- IN EmfPlusRecordType recordType,
- IN UINT flags,
- IN UINT dataSize,
- IN const BYTE * data
- ) const
- {
- return SetStatus(DllExports::GdipPlayMetafileRecord(
- (GpMetafile *)nativeImage,
- recordType,
- flags,
- dataSize,
- data));
- }
-
- // If you're using a printer HDC for the metafile, but you want the
- // metafile rasterized at screen resolution, then use this API to set
- // the rasterization dpi of the metafile to the screen resolution,
- // e.g. 96 dpi or 120 dpi.
- Status SetDownLevelRasterizationLimit(
- IN UINT metafileRasterizationLimitDpi
- )
- {
- return SetStatus(DllExports::GdipSetMetafileDownLevelRasterizationLimit(
- (GpMetafile *)nativeImage,
- metafileRasterizationLimitDpi));
- }
-
- UINT GetDownLevelRasterizationLimit() const
- {
- UINT metafileRasterizationLimitDpi = 0;
-
- SetStatus(DllExports::GdipGetMetafileDownLevelRasterizationLimit(
- (GpMetafile *)nativeImage,
- &metafileRasterizationLimitDpi));
-
- return metafileRasterizationLimitDpi;
- }
-
- static UINT Metafile::EmfToWmfBits(
- IN HENHMETAFILE hemf,
- IN UINT cbData16,
- IN LPBYTE pData16,
- IN INT iMapMode = MM_ANISOTROPIC,
- IN EmfToWmfBitsFlags eFlags = EmfToWmfBitsFlagsDefault
- )
- {
- return DllExports::GdipEmfToWmfBits(
- hemf,
- cbData16,
- pData16,
- iMapMode,
- eFlags);
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- Metafile(const Metafile &);
- Metafile& operator=(const Metafile &);
-
-#endif
-};
-
-#endif // !_METAFILE_H
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusMetafile.h
+*
+* Abstract:
+*
+* Metafile related declarations
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSMETAFILE_H
+#define _GDIPLUSMETAFILE_H
+
+class Metafile : public Image
+{
+public:
+ friend class Image;
+
+ // Read a metafile
+ Metafile()
+ {
+ SetNativeImage(NULL);
+ lastResult = Ok;
+ }
+
+ // Playback a metafile from a HMETAFILE
+ // If deleteWmf is TRUE, then when the metafile is deleted,
+ // the hWmf will also be deleted. Otherwise, it won't be.
+ Metafile(IN HMETAFILE hWmf,
+ IN const APMFileHeader * apmFileHeader,
+ IN BOOL deleteWmf = FALSE)
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipCreateMetafileFromWmf(hWmf, deleteWmf, apmFileHeader, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Playback a metafile from a HENHMETAFILE
+ // If deleteEmf is TRUE, then when the metafile is deleted,
+ // the hEmf will also be deleted. Otherwise, it won't be.
+ Metafile(IN HENHMETAFILE hEmf,
+ IN BOOL deleteEmf = FALSE)
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipCreateMetafileFromEmf(hEmf, deleteEmf, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Playback a metafile from a file
+ Metafile(IN const WCHAR* filename)
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipCreateMetafileFromFile(filename, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Playback a WMF metafile from a file
+ Metafile(IN const WCHAR* filename,
+ IN const APMFileHeader * apmFileHeader
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipCreateMetafileFromWmfFile(filename, apmFileHeader, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Playback a metafile from a stream
+ Metafile(IN IStream* stream)
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipCreateMetafileFromStream(stream, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Record a metafile to memory
+ Metafile(
+ IN HDC referenceHdc,
+ IN EmfType type = EmfTypeEmfPlusDual,
+ IN const WCHAR * description = NULL
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipRecordMetafile(
+ referenceHdc, type, NULL, MetafileFrameUnitGdi,
+ description, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Record a metafile to memory
+ Metafile(
+ IN HDC referenceHdc,
+ IN const RectF & frameRect,
+ IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
+ IN EmfType type = EmfTypeEmfPlusDual,
+ IN const WCHAR * description = NULL
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipRecordMetafile(
+ referenceHdc, type, &frameRect, frameUnit,
+ description, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Record a metafile to memory
+ Metafile(
+ IN HDC referenceHdc,
+ IN const Rect & frameRect,
+ IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
+ IN EmfType type = EmfTypeEmfPlusDual,
+ IN const WCHAR * description = NULL
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipRecordMetafileI(
+ referenceHdc, type, &frameRect, frameUnit,
+ description, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Record a metafile to a file
+ Metafile(
+ IN const WCHAR* fileName,
+ IN HDC referenceHdc,
+ IN EmfType type = EmfTypeEmfPlusDual,
+ IN const WCHAR * description = NULL
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipRecordMetafileFileName(fileName,
+ referenceHdc, type, NULL, MetafileFrameUnitGdi,
+ description, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Record a metafile to a file
+ Metafile(
+ IN const WCHAR* fileName,
+ IN HDC referenceHdc,
+ IN const RectF & frameRect,
+ IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
+ IN EmfType type = EmfTypeEmfPlusDual,
+ IN const WCHAR * description = NULL
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipRecordMetafileFileName(fileName,
+ referenceHdc, type, &frameRect, frameUnit,
+ description, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Record a metafile to a file
+ Metafile(
+ IN const WCHAR* fileName,
+ IN HDC referenceHdc,
+ IN const Rect & frameRect,
+ IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
+ IN EmfType type = EmfTypeEmfPlusDual,
+ IN const WCHAR * description = NULL
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipRecordMetafileFileNameI(fileName,
+ referenceHdc, type, &frameRect, frameUnit,
+ description, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Record a metafile to a stream
+ Metafile(
+ IN IStream * stream,
+ IN HDC referenceHdc,
+ IN EmfType type = EmfTypeEmfPlusDual,
+ IN const WCHAR * description = NULL
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipRecordMetafileStream(stream,
+ referenceHdc, type, NULL, MetafileFrameUnitGdi,
+ description, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Record a metafile to a stream
+ Metafile(
+ IN IStream * stream,
+ IN HDC referenceHdc,
+ IN const RectF & frameRect,
+ IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
+ IN EmfType type = EmfTypeEmfPlusDual,
+ IN const WCHAR * description = NULL
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipRecordMetafileStream(stream,
+ referenceHdc, type, &frameRect, frameUnit,
+ description, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ // Write a metafile to a stream with down-level GDI records
+ Metafile(
+ IN IStream * stream,
+ IN HDC referenceHdc,
+ IN const Rect & frameRect,
+ IN MetafileFrameUnit frameUnit = MetafileFrameUnitGdi,
+ IN EmfType type = EmfTypeEmfPlusDual,
+ IN const WCHAR * description = NULL
+ )
+ {
+ GpMetafile * metafile = NULL;
+
+ lastResult = DllExports::GdipRecordMetafileStreamI(stream,
+ referenceHdc, type, &frameRect, frameUnit,
+ description, &metafile);
+
+ SetNativeImage(metafile);
+ }
+
+ static Status GetMetafileHeader(
+ IN HMETAFILE hWmf,
+ IN const APMFileHeader * apmFileHeader,
+ OUT MetafileHeader * header
+ )
+ {
+ return DllExports::GdipGetMetafileHeaderFromWmf(hWmf, apmFileHeader, header);
+ }
+
+ static Status GetMetafileHeader(
+ IN HENHMETAFILE hEmf,
+ OUT MetafileHeader * header
+ )
+ {
+ return DllExports::GdipGetMetafileHeaderFromEmf(hEmf, header);
+ }
+
+ static Status GetMetafileHeader(
+ IN const WCHAR* filename,
+ OUT MetafileHeader * header
+ )
+ {
+ return DllExports::GdipGetMetafileHeaderFromFile(filename, header);
+ }
+
+ static Status GetMetafileHeader(
+ IN IStream * stream,
+ OUT MetafileHeader * header
+ )
+ {
+ return DllExports::GdipGetMetafileHeaderFromStream(stream, header);
+ }
+
+ Status GetMetafileHeader(
+ OUT MetafileHeader * header
+ ) const
+ {
+ return SetStatus(DllExports::GdipGetMetafileHeaderFromMetafile(
+ (GpMetafile *)nativeImage,
+ header));
+ }
+
+ // Once this method is called, the Metafile object is in an invalid state
+ // and can no longer be used. It is the responsiblity of the caller to
+ // invoke DeleteEnhMetaFile to delete this hEmf.
+
+ HENHMETAFILE GetHENHMETAFILE()
+ {
+ HENHMETAFILE hEmf;
+
+ SetStatus(DllExports::GdipGetHemfFromMetafile((GpMetafile *)nativeImage, &hEmf));
+
+ return hEmf;
+ }
+
+ // Used in conjuction with Graphics::EnumerateMetafile to play an EMF+
+ // The data must be DWORD aligned if it's an EMF or EMF+. It must be
+ // WORD aligned if it's a WMF.
+ Status
+ PlayRecord(
+ IN EmfPlusRecordType recordType,
+ IN UINT flags,
+ IN UINT dataSize,
+ IN const BYTE * data
+ ) const
+ {
+ return SetStatus(DllExports::GdipPlayMetafileRecord(
+ (GpMetafile *)nativeImage,
+ recordType,
+ flags,
+ dataSize,
+ data));
+ }
+
+ // If you're using a printer HDC for the metafile, but you want the
+ // metafile rasterized at screen resolution, then use this API to set
+ // the rasterization dpi of the metafile to the screen resolution,
+ // e.g. 96 dpi or 120 dpi.
+ Status SetDownLevelRasterizationLimit(
+ IN UINT metafileRasterizationLimitDpi
+ )
+ {
+ return SetStatus(DllExports::GdipSetMetafileDownLevelRasterizationLimit(
+ (GpMetafile *)nativeImage,
+ metafileRasterizationLimitDpi));
+ }
+
+ UINT GetDownLevelRasterizationLimit() const
+ {
+ UINT metafileRasterizationLimitDpi = 0;
+
+ SetStatus(DllExports::GdipGetMetafileDownLevelRasterizationLimit(
+ (GpMetafile *)nativeImage,
+ &metafileRasterizationLimitDpi));
+
+ return metafileRasterizationLimitDpi;
+ }
+
+ static UINT Metafile::EmfToWmfBits(
+ IN HENHMETAFILE hemf,
+ IN UINT cbData16,
+ IN LPBYTE pData16,
+ IN INT iMapMode = MM_ANISOTROPIC,
+ IN EmfToWmfBitsFlags eFlags = EmfToWmfBitsFlagsDefault
+ )
+ {
+ return DllExports::GdipEmfToWmfBits(
+ hemf,
+ cbData16,
+ pData16,
+ iMapMode,
+ eFlags);
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ Metafile(const Metafile &);
+ Metafile& operator=(const Metafile &);
+
+#endif
+};
+
+#endif // !_METAFILE_H
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusMetaHeader.h b/core/src/fxge/Microsoft SDK/include/GdiPlusMetaHeader.h
index 79b5bc9533..95ee190f04 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusMetaHeader.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusMetaHeader.h
@@ -1,213 +1,213 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* Metafile headers
-*
-* Abstract:
-*
-* Declarations for various metafile header structures.
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSMETAHEADER_H
-#define _GDIPLUSMETAHEADER_H
-
-typedef struct
-{
- DWORD iType; // Record type EMR_HEADER
- DWORD nSize; // Record size in bytes. This may be greater
- // than the sizeof(ENHMETAHEADER).
- RECTL rclBounds; // Inclusive-inclusive bounds in device units
- RECTL rclFrame; // Inclusive-inclusive Picture Frame of metafile in .01 mm units
- DWORD dSignature; // Signature. Must be ENHMETA_SIGNATURE.
- DWORD nVersion; // Version number
- DWORD nBytes; // Size of the metafile in bytes
- DWORD nRecords; // Number of records in the metafile
- WORD nHandles; // Number of handles in the handle table
- // Handle index zero is reserved.
- WORD sReserved; // Reserved. Must be zero.
- DWORD nDescription; // Number of chars in the unicode description string
- // This is 0 if there is no description string
- DWORD offDescription; // Offset to the metafile description record.
- // This is 0 if there is no description string
- DWORD nPalEntries; // Number of entries in the metafile palette.
- SIZEL szlDevice; // Size of the reference device in pels
- SIZEL szlMillimeters; // Size of the reference device in millimeters
-} ENHMETAHEADER3;
-
-// Aldus Placeable Metafiles
-
-// Placeable Metafiles were created by Aldus Corporation as a non-standard
-// way of specifying how a metafile is mapped and scaled on an output device.
-// Placeable metafiles are quite wide-spread, but not directly supported by
-// the Windows API. To playback a placeable metafile using the Windows API,
-// you will first need to strip the placeable metafile header from the file.
-// This is typically performed by copying the metafile to a temporary file
-// starting at file offset 22 (0x16). The contents of the temporary file may
-// then be used as input to the Windows GetMetaFile(), PlayMetaFile(),
-// CopyMetaFile(), etc. GDI functions.
-
-// Each placeable metafile begins with a 22-byte header,
-// followed by a standard metafile:
-
-#include <pshpack2.h> // set structure packing to 2
-
-typedef struct
-{
- INT16 Left;
- INT16 Top;
- INT16 Right;
- INT16 Bottom;
-} APMRect16;
-
-typedef struct
-{
- UINT32 Key; // GDIP_WMF_ALDUSKEY
- INT16 Hmf; // Metafile HANDLE number (always 0)
- APMRect16 BoundingBox; // Coordinates in metafile units
- INT16 Inch; // Number of metafile units per inch
- UINT32 Reserved; // Reserved (always 0)
- INT16 Checksum; // Checksum value for previous 10 WORDs
-} APMFileHeader;
-
-#include <poppack.h>
-
-// Key contains a special identification value that indicates the presence
-// of a placeable metafile header and is always 0x9AC6CDD7.
-
-// Handle is used to stored the handle of the metafile in memory. When written
-// to disk, this field is not used and will always contains the value 0.
-
-// Left, Top, Right, and Bottom contain the coordinates of the upper-left
-// and lower-right corners of the image on the output device. These are
-// measured in twips.
-
-// A twip (meaning "twentieth of a point") is the logical unit of measurement
-// used in Windows Metafiles. A twip is equal to 1/1440 of an inch. Thus 720
-// twips equal 1/2 inch, while 32,768 twips is 22.75 inches.
-
-// Inch contains the number of twips per inch used to represent the image.
-// Normally, there are 1440 twips per inch; however, this number may be
-// changed to scale the image. A value of 720 indicates that the image is
-// double its normal size, or scaled to a factor of 2:1. A value of 360
-// indicates a scale of 4:1, while a value of 2880 indicates that the image
-// is scaled down in size by a factor of two. A value of 1440 indicates
-// a 1:1 scale ratio.
-
-// Reserved is not used and is always set to 0.
-
-// Checksum contains a checksum value for the previous 10 WORDs in the header.
-// This value can be used in an attempt to detect if the metafile has become
-// corrupted. The checksum is calculated by XORing each WORD value to an
-// initial value of 0.
-
-// If the metafile was recorded with a reference Hdc that was a display.
-#define GDIP_EMFPLUSFLAGS_DISPLAY 0x00000001
-
-class MetafileHeader
-{
-public:
- MetafileType Type;
- UINT Size; // Size of the metafile (in bytes)
- UINT Version; // EMF+, EMF, or WMF version
- UINT EmfPlusFlags;
- REAL DpiX;
- REAL DpiY;
- INT X; // Bounds in device units
- INT Y;
- INT Width;
- INT Height;
- union
- {
- METAHEADER WmfHeader;
- ENHMETAHEADER3 EmfHeader;
- };
- INT EmfPlusHeaderSize; // size of the EMF+ header in file
- INT LogicalDpiX; // Logical Dpi of reference Hdc
- INT LogicalDpiY; // usually valid only for EMF+ files
-
-public:
- // Get the metafile type
- MetafileType GetType() const { return Type; }
-
- // Get the size of the metafile in BYTEs
- UINT GetMetafileSize() const { return Size; }
-
- // If IsEmfPlus, this is the EMF+ version; else it is the WMF or EMF version
- UINT GetVersion() const { return Version; }
-
- // Get the EMF+ flags associated with the metafile
- UINT GetEmfPlusFlags() const { return EmfPlusFlags; }
-
- // Get the X Dpi of the metafile
- REAL GetDpiX() const { return DpiX; }
-
- // Get the Y Dpi of the metafile
- REAL GetDpiY() const { return DpiY; }
-
- // Get the bounds of the metafile in device units
- VOID GetBounds (OUT Rect *rect) const
- {
- rect->X = X;
- rect->Y = Y;
- rect->Width = Width;
- rect->Height = Height;
- }
-
- // Is it any type of WMF (standard or Aldus Placeable Metafile)?
- BOOL IsWmf() const
- {
- return ((Type == MetafileTypeWmf) || (Type == MetafileTypeWmfAldus));
- }
-
- // Is this an Aldus Placeable Metafile?
- BOOL IsWmfAldus() const { return (Type == MetafileTypeWmf); }
-
- // Is this an EMF (not an EMF+)?
- BOOL IsEmf() const { return (Type == MetafileTypeEmf); }
-
- // Is this an EMF or EMF+ file?
- BOOL IsEmfOrEmfPlus() const { return (Type >= MetafileTypeEmf); }
-
- // Is this an EMF+ file?
- BOOL IsEmfPlus() const { return (Type >= MetafileTypeEmfPlusOnly); }
-
- // Is this an EMF+ dual (has dual, down-level records) file?
- BOOL IsEmfPlusDual() const { return (Type == MetafileTypeEmfPlusDual); }
-
- // Is this an EMF+ only (no dual records) file?
- BOOL IsEmfPlusOnly() const { return (Type == MetafileTypeEmfPlusOnly); }
-
- // If it's an EMF+ file, was it recorded against a display Hdc?
- BOOL IsDisplay() const
- {
- return (IsEmfPlus() &&
- ((EmfPlusFlags & GDIP_EMFPLUSFLAGS_DISPLAY) != 0));
- }
-
- // Get the WMF header of the metafile (if it is a WMF)
- const METAHEADER * GetWmfHeader() const
- {
- if (IsWmf())
- {
- return &WmfHeader;
- }
- return NULL;
- }
-
- // Get the EMF header of the metafile (if it is an EMF)
- const ENHMETAHEADER3 * GetEmfHeader() const
- {
- if (IsEmfOrEmfPlus())
- {
- return &EmfHeader;
- }
- return NULL;
- }
-};
-
-#endif
-
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* Metafile headers
+*
+* Abstract:
+*
+* Declarations for various metafile header structures.
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSMETAHEADER_H
+#define _GDIPLUSMETAHEADER_H
+
+typedef struct
+{
+ DWORD iType; // Record type EMR_HEADER
+ DWORD nSize; // Record size in bytes. This may be greater
+ // than the sizeof(ENHMETAHEADER).
+ RECTL rclBounds; // Inclusive-inclusive bounds in device units
+ RECTL rclFrame; // Inclusive-inclusive Picture Frame of metafile in .01 mm units
+ DWORD dSignature; // Signature. Must be ENHMETA_SIGNATURE.
+ DWORD nVersion; // Version number
+ DWORD nBytes; // Size of the metafile in bytes
+ DWORD nRecords; // Number of records in the metafile
+ WORD nHandles; // Number of handles in the handle table
+ // Handle index zero is reserved.
+ WORD sReserved; // Reserved. Must be zero.
+ DWORD nDescription; // Number of chars in the unicode description string
+ // This is 0 if there is no description string
+ DWORD offDescription; // Offset to the metafile description record.
+ // This is 0 if there is no description string
+ DWORD nPalEntries; // Number of entries in the metafile palette.
+ SIZEL szlDevice; // Size of the reference device in pels
+ SIZEL szlMillimeters; // Size of the reference device in millimeters
+} ENHMETAHEADER3;
+
+// Aldus Placeable Metafiles
+
+// Placeable Metafiles were created by Aldus Corporation as a non-standard
+// way of specifying how a metafile is mapped and scaled on an output device.
+// Placeable metafiles are quite wide-spread, but not directly supported by
+// the Windows API. To playback a placeable metafile using the Windows API,
+// you will first need to strip the placeable metafile header from the file.
+// This is typically performed by copying the metafile to a temporary file
+// starting at file offset 22 (0x16). The contents of the temporary file may
+// then be used as input to the Windows GetMetaFile(), PlayMetaFile(),
+// CopyMetaFile(), etc. GDI functions.
+
+// Each placeable metafile begins with a 22-byte header,
+// followed by a standard metafile:
+
+#include <pshpack2.h> // set structure packing to 2
+
+typedef struct
+{
+ INT16 Left;
+ INT16 Top;
+ INT16 Right;
+ INT16 Bottom;
+} APMRect16;
+
+typedef struct
+{
+ UINT32 Key; // GDIP_WMF_ALDUSKEY
+ INT16 Hmf; // Metafile HANDLE number (always 0)
+ APMRect16 BoundingBox; // Coordinates in metafile units
+ INT16 Inch; // Number of metafile units per inch
+ UINT32 Reserved; // Reserved (always 0)
+ INT16 Checksum; // Checksum value for previous 10 WORDs
+} APMFileHeader;
+
+#include <poppack.h>
+
+// Key contains a special identification value that indicates the presence
+// of a placeable metafile header and is always 0x9AC6CDD7.
+
+// Handle is used to stored the handle of the metafile in memory. When written
+// to disk, this field is not used and will always contains the value 0.
+
+// Left, Top, Right, and Bottom contain the coordinates of the upper-left
+// and lower-right corners of the image on the output device. These are
+// measured in twips.
+
+// A twip (meaning "twentieth of a point") is the logical unit of measurement
+// used in Windows Metafiles. A twip is equal to 1/1440 of an inch. Thus 720
+// twips equal 1/2 inch, while 32,768 twips is 22.75 inches.
+
+// Inch contains the number of twips per inch used to represent the image.
+// Normally, there are 1440 twips per inch; however, this number may be
+// changed to scale the image. A value of 720 indicates that the image is
+// double its normal size, or scaled to a factor of 2:1. A value of 360
+// indicates a scale of 4:1, while a value of 2880 indicates that the image
+// is scaled down in size by a factor of two. A value of 1440 indicates
+// a 1:1 scale ratio.
+
+// Reserved is not used and is always set to 0.
+
+// Checksum contains a checksum value for the previous 10 WORDs in the header.
+// This value can be used in an attempt to detect if the metafile has become
+// corrupted. The checksum is calculated by XORing each WORD value to an
+// initial value of 0.
+
+// If the metafile was recorded with a reference Hdc that was a display.
+#define GDIP_EMFPLUSFLAGS_DISPLAY 0x00000001
+
+class MetafileHeader
+{
+public:
+ MetafileType Type;
+ UINT Size; // Size of the metafile (in bytes)
+ UINT Version; // EMF+, EMF, or WMF version
+ UINT EmfPlusFlags;
+ REAL DpiX;
+ REAL DpiY;
+ INT X; // Bounds in device units
+ INT Y;
+ INT Width;
+ INT Height;
+ union
+ {
+ METAHEADER WmfHeader;
+ ENHMETAHEADER3 EmfHeader;
+ };
+ INT EmfPlusHeaderSize; // size of the EMF+ header in file
+ INT LogicalDpiX; // Logical Dpi of reference Hdc
+ INT LogicalDpiY; // usually valid only for EMF+ files
+
+public:
+ // Get the metafile type
+ MetafileType GetType() const { return Type; }
+
+ // Get the size of the metafile in BYTEs
+ UINT GetMetafileSize() const { return Size; }
+
+ // If IsEmfPlus, this is the EMF+ version; else it is the WMF or EMF version
+ UINT GetVersion() const { return Version; }
+
+ // Get the EMF+ flags associated with the metafile
+ UINT GetEmfPlusFlags() const { return EmfPlusFlags; }
+
+ // Get the X Dpi of the metafile
+ REAL GetDpiX() const { return DpiX; }
+
+ // Get the Y Dpi of the metafile
+ REAL GetDpiY() const { return DpiY; }
+
+ // Get the bounds of the metafile in device units
+ VOID GetBounds (OUT Rect *rect) const
+ {
+ rect->X = X;
+ rect->Y = Y;
+ rect->Width = Width;
+ rect->Height = Height;
+ }
+
+ // Is it any type of WMF (standard or Aldus Placeable Metafile)?
+ BOOL IsWmf() const
+ {
+ return ((Type == MetafileTypeWmf) || (Type == MetafileTypeWmfAldus));
+ }
+
+ // Is this an Aldus Placeable Metafile?
+ BOOL IsWmfAldus() const { return (Type == MetafileTypeWmf); }
+
+ // Is this an EMF (not an EMF+)?
+ BOOL IsEmf() const { return (Type == MetafileTypeEmf); }
+
+ // Is this an EMF or EMF+ file?
+ BOOL IsEmfOrEmfPlus() const { return (Type >= MetafileTypeEmf); }
+
+ // Is this an EMF+ file?
+ BOOL IsEmfPlus() const { return (Type >= MetafileTypeEmfPlusOnly); }
+
+ // Is this an EMF+ dual (has dual, down-level records) file?
+ BOOL IsEmfPlusDual() const { return (Type == MetafileTypeEmfPlusDual); }
+
+ // Is this an EMF+ only (no dual records) file?
+ BOOL IsEmfPlusOnly() const { return (Type == MetafileTypeEmfPlusOnly); }
+
+ // If it's an EMF+ file, was it recorded against a display Hdc?
+ BOOL IsDisplay() const
+ {
+ return (IsEmfPlus() &&
+ ((EmfPlusFlags & GDIP_EMFPLUSFLAGS_DISPLAY) != 0));
+ }
+
+ // Get the WMF header of the metafile (if it is a WMF)
+ const METAHEADER * GetWmfHeader() const
+ {
+ if (IsWmf())
+ {
+ return &WmfHeader;
+ }
+ return NULL;
+ }
+
+ // Get the EMF header of the metafile (if it is an EMF)
+ const ENHMETAHEADER3 * GetEmfHeader() const
+ {
+ if (IsEmfOrEmfPlus())
+ {
+ return &EmfHeader;
+ }
+ return NULL;
+ }
+};
+
+#endif
+
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusPath.h b/core/src/fxge/Microsoft SDK/include/GdiPlusPath.h
index cff0e1d9ce..99f8afdda8 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusPath.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusPath.h
@@ -1,1686 +1,1686 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusPath.h
-*
-* Abstract:
-*
-* Path related declarations
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSPATH_H
-#define _GDIPLUSPATH_H
-
-class GraphicsPath : public GdiplusBase
-{
-public:
- friend class Graphics;
- friend class Region;
- friend class PathGradientBrush;
- friend class GraphicsPathIterator;
- friend class CustomLineCap;
-
- // Path constructors
-
- GraphicsPath(IN FillMode fillMode = FillModeAlternate)
- {
- nativePath = NULL;
- lastResult = DllExports::GdipCreatePath(fillMode, &nativePath);
- }
-
- GraphicsPath(IN const PointF* points,
- IN const BYTE* types,
- IN INT count,
- IN FillMode fillMode = FillModeAlternate)
- {
- nativePath = NULL;
- lastResult = DllExports::GdipCreatePath2(points,
- types,
- count,
- fillMode,
- &nativePath);
- }
-
- GraphicsPath(IN const Point* points,
- IN const BYTE* types,
- IN INT count,
- IN FillMode fillMode = FillModeAlternate)
- {
- nativePath = NULL;
- lastResult = DllExports::GdipCreatePath2I(points,
- types,
- count,
- fillMode,
- &nativePath);
- }
-
- ~GraphicsPath()
- {
- DllExports::GdipDeletePath(nativePath);
- }
-
- /**
- * Make a copy of the current path object
- */
- GraphicsPath* Clone() const
- {
- GpPath *clonepath = NULL;
-
- SetStatus(DllExports::GdipClonePath(nativePath, &clonepath));
-
- return new GraphicsPath(clonepath);
- }
-
- /**
- * Reset the path object to empty (and fill mode to FillModeAlternate)
- */
- Status Reset()
- {
- return SetStatus(DllExports::GdipResetPath(nativePath));
- }
-
- /**
- * Get path fill mode information
- */
- FillMode GetFillMode() const
- {
- FillMode fillmode = FillModeAlternate;
-
- SetStatus(DllExports::GdipGetPathFillMode(nativePath, &fillmode));
-
- return fillmode;
- }
-
- /**
- * Set path fill mode information
- */
- Status SetFillMode(IN FillMode fillmode)
- {
- return SetStatus(DllExports::GdipSetPathFillMode(nativePath, fillmode));
- }
-
- /**
- * Set/get path data
- */
- Status GetPathData(OUT PathData* pathData) const
- {
- if (pathData == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- INT count = GetPointCount();
-
- if ((count <= 0) || (pathData->Count>0 && pathData->Count<count))
- {
- pathData->Count = 0;
- if (pathData->Points)
- {
- delete pathData->Points;
- pathData->Points = NULL;
- }
-
- if (pathData->Types)
- {
- delete pathData->Types;
- pathData->Types = NULL;
- }
-
- if (count <= 0)
- {
- return lastResult;
- }
- }
-
- if (pathData->Count == 0)
- {
- pathData->Points = new PointF[count];
- if (pathData->Points == NULL)
- {
- return SetStatus(OutOfMemory);
-
- }
- pathData->Types = new byte[count];
- if (pathData->Types == NULL)
- {
- delete pathData->Points;
- pathData->Points = NULL;
-
- return SetStatus(OutOfMemory);
- }
- pathData->Count = count;
- }
-
- return SetStatus(DllExports::GdipGetPathData(nativePath, pathData));
- }
-
- /**
- * Start/end a subpath
- */
- Status StartFigure()
- {
- return SetStatus(DllExports::GdipStartPathFigure(nativePath));
- }
-
- Status CloseFigure()
- {
- return SetStatus(DllExports::GdipClosePathFigure(nativePath));
- }
-
- Status CloseAllFigures()
- {
- return SetStatus(DllExports::GdipClosePathFigures(nativePath));
- }
-
- Status SetMarker()
- {
- return SetStatus(DllExports::GdipSetPathMarker(nativePath));
- }
-
- Status ClearMarkers()
- {
- return SetStatus(DllExports::GdipClearPathMarkers(nativePath));
- }
-
- Status Reverse()
- {
- return SetStatus(DllExports::GdipReversePath(nativePath));
- }
-
- Status GetLastPoint(OUT PointF* lastPoint) const
- {
- return SetStatus(DllExports::GdipGetPathLastPoint(nativePath, lastPoint));
- }
-
- /**
- * Add lines to the path object
- */
- // float version
- Status AddLine(IN const PointF& pt1,
- IN const PointF& pt2)
- {
- return AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
- }
-
- Status AddLine(IN REAL x1,
- IN REAL y1,
- IN REAL x2,
- IN REAL y2)
- {
- return SetStatus(DllExports::GdipAddPathLine(nativePath, x1, y1, x2, y2));
- }
-
- Status AddLines(IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathLine2(nativePath, points, count));
- }
-
- // integer version
- Status AddLine(IN const Point& pt1,
- IN const Point& pt2)
- {
- return AddLine(pt1.X,
- pt1.Y,
- pt2.X,
- pt2.Y);
- }
-
- Status AddLine(IN INT x1,
- IN INT y1,
- IN INT x2,
- IN INT y2)
- {
- return SetStatus(DllExports::GdipAddPathLineI(nativePath,
- x1,
- y1,
- x2,
- y2));
- }
-
- Status AddLines(IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathLine2I(nativePath,
- points,
- count));
- }
-
- /**
- * Add an arc to the path object
- */
- // float version
- Status AddArc(IN const RectF& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return AddArc(rect.X, rect.Y, rect.Width, rect.Height,
- startAngle, sweepAngle);
- }
-
- Status AddArc(IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipAddPathArc(nativePath, x, y, width, height,
- startAngle, sweepAngle));
- }
-
- // integer version
- Status AddArc(IN const Rect& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return AddArc(rect.X, rect.Y, rect.Width, rect.Height,
- startAngle, sweepAngle);
- }
-
- Status AddArc(IN INT x,
- IN INT y,
- IN INT width,
- IN INT height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipAddPathArcI(nativePath,
- x,
- y,
- width,
- height,
- startAngle,
- sweepAngle));
- }
-
- /**
- * Add Bezier curves to the path object
- */
- // float version
- Status AddBezier(IN const PointF& pt1,
- IN const PointF& pt2,
- IN const PointF& pt3,
- IN const PointF& pt4)
- {
- return AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X,
- pt4.Y);
- }
-
- Status AddBezier(IN REAL x1,
- IN REAL y1,
- IN REAL x2,
- IN REAL y2,
- IN REAL x3,
- IN REAL y3,
- IN REAL x4,
- IN REAL y4)
- {
- return SetStatus(DllExports::GdipAddPathBezier(nativePath, x1, y1, x2, y2,
- x3, y3, x4, y4));
- }
-
- Status AddBeziers(IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathBeziers(nativePath, points, count));
- }
-
- // integer version
- Status AddBezier(IN const Point& pt1,
- IN const Point& pt2,
- IN const Point& pt3,
- IN const Point& pt4)
- {
- return AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X,
- pt4.Y);
- }
-
- Status AddBezier(IN INT x1,
- IN INT y1,
- IN INT x2,
- IN INT y2,
- IN INT x3,
- IN INT y3,
- IN INT x4,
- IN INT y4)
- {
- return SetStatus(DllExports::GdipAddPathBezierI(nativePath,
- x1,
- y1,
- x2,
- y2,
- x3,
- y3,
- x4,
- y4));
- }
-
- Status AddBeziers(IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathBeziersI(nativePath,
- points,
- count));
- }
-
- // float version
- Status AddCurve(IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathCurve(nativePath,
- points,
- count));
- }
-
- Status AddCurve(IN const PointF* points,
- IN INT count,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipAddPathCurve2(nativePath,
- points,
- count,
- tension));
- }
-
- Status AddCurve(IN const PointF* points,
- IN INT count,
- IN INT offset,
- IN INT numberOfSegments,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipAddPathCurve3(nativePath,
- points,
- count,
- offset,
- numberOfSegments,
- tension));
- }
-
- // integer version
- Status AddCurve(IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathCurveI(nativePath,
- points,
- count));
- }
-
- Status AddCurve(IN const Point* points,
- IN INT count,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipAddPathCurve2I(nativePath,
- points,
- count,
- tension));
- }
-
- Status AddCurve(IN const Point* points,
- IN INT count,
- IN INT offset,
- IN INT numberOfSegments,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipAddPathCurve3I(nativePath,
- points,
- count,
- offset,
- numberOfSegments,
- tension));
- }
-
- // float version
- Status AddClosedCurve(IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathClosedCurve(nativePath,
- points,
- count));
- }
-
- Status AddClosedCurve(IN const PointF* points,
- IN INT count,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipAddPathClosedCurve2(nativePath,
- points,
- count,
- tension));
- }
-
- // integer version
- Status AddClosedCurve(IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathClosedCurveI(nativePath,
- points,
- count));
- }
-
-
- Status AddClosedCurve(IN const Point* points,
- IN INT count,
- IN REAL tension)
- {
- return SetStatus(DllExports::GdipAddPathClosedCurve2I(nativePath,
- points,
- count,
- tension));
- }
-
-
- /**
- * Add closed shapes to the path object
- */
-
- // float version
- Status AddRectangle(IN const RectF& rect)
- {
- return SetStatus(DllExports::GdipAddPathRectangle(nativePath,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height));
- }
-
- Status AddRectangles(IN const RectF* rects,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathRectangles(nativePath,
- rects,
- count));
- }
-
- // integer version
- Status AddRectangle(IN const Rect& rect)
- {
- return SetStatus(DllExports::GdipAddPathRectangleI(nativePath,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height));
- }
-
- Status AddRectangles(IN const Rect* rects, INT count)
- {
- return SetStatus(DllExports::GdipAddPathRectanglesI(nativePath,
- rects,
- count));
- }
-
- // float version
- Status AddEllipse(IN const RectF& rect)
- {
- return AddEllipse(rect.X, rect.Y, rect.Width, rect.Height);
- }
-
- Status AddEllipse(IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height)
- {
- return SetStatus(DllExports::GdipAddPathEllipse(nativePath,
- x,
- y,
- width,
- height));
- }
-
- // integer version
- Status AddEllipse(IN const Rect& rect)
- {
- return AddEllipse(rect.X, rect.Y, rect.Width, rect.Height);
- }
-
- Status AddEllipse(IN INT x,
- IN INT y,
- IN INT width,
- IN INT height)
- {
- return SetStatus(DllExports::GdipAddPathEllipseI(nativePath,
- x,
- y,
- width,
- height));
- }
-
- // float version
- Status AddPie(IN const RectF& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return AddPie(rect.X, rect.Y, rect.Width, rect.Height, startAngle,
- sweepAngle);
- }
-
- Status AddPie(IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipAddPathPie(nativePath, x, y, width, height,
- startAngle, sweepAngle));
- }
-
- // integer version
- Status AddPie(IN const Rect& rect,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return AddPie(rect.X,
- rect.Y,
- rect.Width,
- rect.Height,
- startAngle,
- sweepAngle);
- }
-
- Status AddPie(IN INT x,
- IN INT y,
- IN INT width,
- IN INT height,
- IN REAL startAngle,
- IN REAL sweepAngle)
- {
- return SetStatus(DllExports::GdipAddPathPieI(nativePath,
- x,
- y,
- width,
- height,
- startAngle,
- sweepAngle));
- }
-
- // float version
- Status AddPolygon(IN const PointF* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathPolygon(nativePath, points, count));
- }
-
- // integer version
- Status AddPolygon(IN const Point* points,
- IN INT count)
- {
- return SetStatus(DllExports::GdipAddPathPolygonI(nativePath, points, count));
- }
-
- Status AddPath(IN const GraphicsPath* addingPath,
- IN BOOL connect)
- {
- GpPath* nativePath2 = NULL;
- if(addingPath)
- nativePath2 = addingPath->nativePath;
-
- return SetStatus(DllExports::GdipAddPathPath(nativePath, nativePath2, connect));
- }
-
- // AddString point version
-
- Status AddString(
- IN const WCHAR *string,
- IN INT length,
- IN const FontFamily *family,
- IN INT style,
- IN REAL emSize, // In world units
- IN const PointF &origin,
- IN const StringFormat *format
- )
- {
- RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
-
- return SetStatus(DllExports::GdipAddPathString(
- nativePath,
- string,
- length,
- family ? family->nativeFamily : NULL,
- style,
- emSize,
- &rect,
- format ? format->nativeFormat : NULL
- ));
- }
-
- // AddString rectangle version
-
- Status AddString(
- IN const WCHAR *string,
- IN INT length,
- IN const FontFamily *family,
- IN INT style,
- IN REAL emSize, // In world units
- IN const RectF &layoutRect,
- IN const StringFormat *format
- )
- {
- return SetStatus(DllExports::GdipAddPathString(
- nativePath,
- string,
- length,
- family ? family->nativeFamily : NULL,
- style,
- emSize,
- &layoutRect,
- format ? format->nativeFormat : NULL
- ));
- }
-
- Status AddString(
- IN const WCHAR *string,
- IN INT length,
- IN const FontFamily *family,
- IN INT style,
- IN REAL emSize, // In world units
- IN const Point &origin,
- IN const StringFormat *format
- )
- {
- Rect rect(origin.X, origin.Y, 0, 0);
-
- return SetStatus(DllExports::GdipAddPathStringI(
- nativePath,
- string,
- length,
- family ? family->nativeFamily : NULL,
- style,
- emSize,
- &rect,
- format ? format->nativeFormat : NULL
- ));
- }
-
- // AddString rectangle version
-
- Status AddString(
- IN const WCHAR *string,
- IN INT length,
- IN const FontFamily *family,
- IN INT style,
- IN REAL emSize, // In world units
- IN const Rect &layoutRect,
- IN const StringFormat *format
- )
- {
- return SetStatus(DllExports::GdipAddPathStringI(
- nativePath,
- string,
- length,
- family ? family->nativeFamily : NULL,
- style,
- emSize,
- &layoutRect,
- format ? format->nativeFormat : NULL
- ));
- }
-
- /**
- * Transforms the path object
- */
- Status Transform(IN const Matrix* matrix)
- {
- if(matrix)
- return SetStatus(DllExports::GdipTransformPath(nativePath, matrix->nativeMatrix));
- else
- return Ok; // No need to transform.
- }
-
- /**
- * Get the bounds of the path object with the given transform.
- * This is not always the tightest bounds.
- *
- * Defined in GdiplusGraphics.h.
- */
- Status GetBounds(OUT RectF* bounds,
- IN const Matrix* matrix = NULL,
- IN const Pen* pen = NULL) const;
-
- // integer version (defined in GdiplusGraphics.h)
- Status GetBounds(OUT Rect* bounds,
- IN const Matrix* matrix = NULL,
- IN const Pen* pen = NULL) const;
-
- /**
- * Flatten the path object
- * Once this is called, the resultant path is made of line segments and
- * the original path information is lost.
- * When matrix = NULL, the identity matrix is assumed.
- */
- Status Flatten(IN const Matrix* matrix = NULL,
- IN REAL flatness = FlatnessDefault)
- {
- GpMatrix* nativeMatrix = NULL;
- if(matrix)
- {
- nativeMatrix = matrix->nativeMatrix;
- }
-
- return SetStatus(DllExports::GdipFlattenPath(
- nativePath,
- nativeMatrix,
- flatness
- ));
- }
-
-#ifdef DCR_USE_NEW_202903
-
- Status Widen(
- IN const Pen* pen,
- IN const Matrix* matrix = NULL,
- IN REAL flatness = FlatnessDefault
- )
- {
- GpMatrix* nativeMatrix = NULL;
- if(matrix)
- nativeMatrix = matrix->nativeMatrix;
-
- return SetStatus(DllExports::GdipWidenPath(
- nativePath,
- pen->nativePen,
- nativeMatrix,
- flatness
- ));
- }
-
-#else
-
- /**
- * Widen the path object
- * When removeSelfIntersects is TRUE, this returns the widened path
- * without self intersections.
- * When it is FALSE, it returns the widened path with selfintersections.
- * The latter is faster and is usually safficient for filling.
- */
- Status Widen(IN const Pen* pen,
- IN const Matrix* matrix = NULL,
- IN BOOL removeSelfIntersects = TRUE)
- {
- GpMatrix* nativeMatrix = NULL;
- if(matrix)
- nativeMatrix = matrix->nativeMatrix;
-
- return SetStatus(DllExports::GdipWidenPathWithMinimumResolutions(nativePath, pen->nativePen,
- 0, 0, nativeMatrix, removeSelfIntersects));
- }
-
- /**
- * Widen the path object
- * This is equivalent to Widen() method except that
- * The widths of the widened path are larger than the given
- * minimum resolutions in x and y coordinates after the transform.
- * This is usefull when widening a path with the limited device resolutions.
- */
-
- Status Widen(IN const Pen* pen,
- IN REAL minXres,
- IN REAL minYres,
- IN const Matrix* matrix = NULL,
- IN BOOL removeSelfIntersects = TRUE)
- {
- GpMatrix* nativeMatrix = NULL;
- if(matrix)
- nativeMatrix = matrix->nativeMatrix;
-
- return SetStatus(DllExports::GdipWidenPathWithMinimumResolutions(nativePath, pen->nativePen,
- minXres, minYres, nativeMatrix, removeSelfIntersects));
- }
-
-#endif // DCR_USE_NEW_202903
-
- Status Outline(
- IN const Matrix *matrix = NULL,
- IN REAL flatness = FlatnessDefault
- )
- {
- GpMatrix* nativeMatrix = NULL;
- if(matrix)
- {
- nativeMatrix = matrix->nativeMatrix;
- }
-
- return SetStatus(DllExports::GdipWindingModeOutline(
- nativePath, nativeMatrix, flatness
- ));
- }
-
- /**
- * Warp the path object
- * Once this is called, the resultant path is made of line segments and
- * the original path information is lost.
- * When matrix = NULL, the identity matrix is assumed.
- */
- Status Warp(IN const PointF* destPoints,
- IN INT count,
- IN const RectF& srcRect,
- IN const Matrix* matrix = NULL,
- IN WarpMode warpMode = WarpModePerspective,
- IN REAL flatness = FlatnessDefault)
- {
- GpMatrix* nativeMatrix = NULL;
- if(matrix)
- nativeMatrix = matrix->nativeMatrix;
-
- return SetStatus(DllExports::GdipWarpPath(
- nativePath,
- nativeMatrix,
- destPoints,
- count,
- srcRect.X,
- srcRect.Y,
- srcRect.Width,
- srcRect.Height,
- warpMode,
- flatness));
- }
-
- /**
- * Return the number of points in the current path
- */
- INT GetPointCount() const
- {
- INT count = 0;
-
- SetStatus(DllExports::GdipGetPointCount(nativePath, &count));
-
- return count;
- }
-
- /**
- * Return the path point type information
- */
- Status GetPathTypes(OUT BYTE* types,
- IN INT count) const
- {
- return SetStatus(DllExports::GdipGetPathTypes(nativePath, types, count));
- }
-
- /**
- * Return the path point coordinate information
- * @notes Should there be PathData that contains types[] and points[]
- * for get & set purposes.
- */
- Status GetPathPoints(OUT PointF* points,
- IN INT count) const
- {
- return SetStatus(DllExports::GdipGetPathPoints(nativePath, points, count));
- }
-
- // integer version
- Status GetPathPoints(OUT Point* points,
- IN INT count) const
- {
- return SetStatus(DllExports::GdipGetPathPointsI(nativePath, points, count));
- }
-
- Status GetLastStatus() const
- {
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
- }
-
- /**
- * Hit testing operations
- *
- * inline implementation is in gdiplusgraphics.h.
- */
-
- BOOL IsVisible(IN const PointF& point,
- IN const Graphics* g = NULL) const
- {
- return IsVisible(point.X, point.Y, g);
- }
-
- BOOL IsVisible(IN REAL x,
- IN REAL y,
- IN const Graphics* g = NULL) const;
-
- BOOL IsVisible(IN const Point& point,
- IN const Graphics* g = NULL) const
- {
- return IsVisible(point.X, point.Y, g);
- }
-
- BOOL IsVisible(IN INT x,
- IN INT y,
- IN const Graphics* g = NULL) const;
-
- BOOL IsOutlineVisible(IN const PointF& point,
- IN const Pen* pen,
- IN const Graphics* g = NULL) const
- {
- return IsOutlineVisible(point.X, point.Y, pen, g);
- }
-
- BOOL IsOutlineVisible(IN REAL x,
- IN REAL y,
- IN const Pen* pen,
- IN const Graphics* g = NULL) const;
-
- BOOL IsOutlineVisible(IN const Point& point,
- IN const Pen* pen,
- IN const Graphics* g = NULL) const
- {
- return IsOutlineVisible(point.X, point.Y, pen, g);
- }
-
- BOOL IsOutlineVisible(IN INT x,
- IN INT y,
- IN const Pen* pen,
- IN const Graphics* g = NULL) const;
-
-protected:
-
- GraphicsPath(const GraphicsPath& path)
- {
- GpPath *clonepath = NULL;
- SetStatus(DllExports::GdipClonePath(path.nativePath, &clonepath));
- SetNativePath(clonepath);
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- GraphicsPath& operator=(const GraphicsPath &);
-protected:
-
-#else
-
- GraphicsPath& operator=(const GraphicsPath& path)
- {
- path;
- SetStatus(NotImplemented);
- return *this;
- }
-
-#endif
-
- GraphicsPath(GpPath* nativePath)
- {
- lastResult = Ok;
- SetNativePath(nativePath);
- }
-
- VOID SetNativePath(GpPath *nativePath)
- {
- this->nativePath = nativePath;
- }
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
-protected:
- GpPath* nativePath;
- mutable Status lastResult;
-};
-
-
-//--------------------------------------------------------------------------
-// GraphisPathIterator class
-//--------------------------------------------------------------------------
-
-class GraphicsPathIterator : public GdiplusBase
-{
-public:
-
- GraphicsPathIterator(IN const GraphicsPath* path)
- {
- GpPath* nativePath = NULL;
- if(path)
- nativePath = path->nativePath;
-
- GpPathIterator *iter = NULL;
- lastResult = DllExports::GdipCreatePathIter(&iter, nativePath);
- SetNativeIterator(iter);
- }
-
- ~GraphicsPathIterator()
- {
- DllExports::GdipDeletePathIter(nativeIterator);
- }
-
-
- INT NextSubpath(OUT INT* startIndex,
- OUT INT* endIndex,
- OUT BOOL* isClosed)
- {
- INT resultCount;
-
- SetStatus(DllExports::GdipPathIterNextSubpath(nativeIterator,
- &resultCount, startIndex, endIndex, isClosed));
-
- return resultCount;
- }
-
-
- INT NextSubpath(IN const GraphicsPath* path,
- OUT BOOL* isClosed)
- {
- GpPath* nativePath = NULL;
-
- INT resultCount;
-
- if(path)
- nativePath= path->nativePath;
-
- SetStatus(DllExports::GdipPathIterNextSubpathPath(nativeIterator,
- &resultCount, nativePath, isClosed));
-
- return resultCount;
- }
-
- INT NextPathType(OUT BYTE* pathType,
- OUT INT* startIndex,
- OUT INT* endIndex)
- {
- INT resultCount;
-
- SetStatus(DllExports::GdipPathIterNextPathType(nativeIterator,
- &resultCount, pathType, startIndex, endIndex));
-
- return resultCount;
- }
-
- INT NextMarker(OUT INT* startIndex,
- OUT INT* endIndex)
- {
- INT resultCount;
-
- SetStatus(DllExports::GdipPathIterNextMarker(nativeIterator,
- &resultCount, startIndex, endIndex));
-
- return resultCount;
- }
-
-
- INT NextMarker(IN const GraphicsPath* path)
- {
- GpPath* nativePath = NULL;
-
- INT resultCount;
-
- if(path)
- nativePath= path->nativePath;
-
- SetStatus(DllExports::GdipPathIterNextMarkerPath(nativeIterator,
- &resultCount, nativePath));
-
- return resultCount;
- }
-
- INT GetCount() const
- {
- INT resultCount;
-
- SetStatus(DllExports::GdipPathIterGetCount(nativeIterator, &resultCount));
-
- return resultCount;
- }
-
- INT GetSubpathCount() const
- {
- INT resultCount;
-
- SetStatus(DllExports::GdipPathIterGetSubpathCount(nativeIterator, &resultCount));
-
- return resultCount;
- }
-
- BOOL HasCurve() const
- {
- BOOL hasCurve;
-
- SetStatus(DllExports::GdipPathIterHasCurve(nativeIterator, &hasCurve));
-
- return hasCurve;
- }
-
- VOID Rewind()
- {
- SetStatus(DllExports::GdipPathIterRewind(nativeIterator));
- }
-
- INT Enumerate(OUT PointF *points,
- OUT BYTE *types,
- IN INT count)
- {
- INT resultCount;
-
- SetStatus(DllExports::GdipPathIterEnumerate(nativeIterator,
- &resultCount, points, types, count));
-
- return resultCount;
- }
-
- INT CopyData(OUT PointF* points,
- OUT BYTE* types,
- IN INT startIndex,
- IN INT endIndex)
- {
- INT resultCount;
-
- SetStatus(DllExports::GdipPathIterCopyData(nativeIterator,
- &resultCount, points, types, startIndex, endIndex));
-
- return resultCount;
- }
-
- Status GetLastStatus() const
- {
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- GraphicsPathIterator(const GraphicsPathIterator &);
- GraphicsPathIterator& operator=(const GraphicsPathIterator &);
-
-#endif
-
-protected:
- VOID SetNativeIterator(GpPathIterator *nativeIterator)
- {
- this->nativeIterator = nativeIterator;
- }
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
-protected:
- GpPathIterator* nativeIterator;
- mutable Status lastResult;
-};
-
-
-//--------------------------------------------------------------------------
-// Represent polygon gradient brush object
-//--------------------------------------------------------------------------
-
-class PathGradientBrush : public Brush
-{
-public:
- friend class Pen;
-
- PathGradientBrush(
- IN const PointF* points,
- IN INT count,
- IN WrapMode wrapMode = WrapModeClamp)
- {
- GpPathGradient *brush = NULL;
-
- lastResult = DllExports::GdipCreatePathGradient(
- points, count,
- wrapMode, &brush);
- SetNativeBrush(brush);
- }
-
- PathGradientBrush(
- IN const Point* points,
- IN INT count,
- IN WrapMode wrapMode = WrapModeClamp)
- {
- GpPathGradient *brush = NULL;
-
- lastResult = DllExports::GdipCreatePathGradientI(
- points, count,
- wrapMode, &brush);
-
- SetNativeBrush(brush);
- }
-
- PathGradientBrush(
- IN const GraphicsPath* path
- )
- {
- GpPathGradient *brush = NULL;
-
- lastResult = DllExports::GdipCreatePathGradientFromPath(
- path->nativePath, &brush);
- SetNativeBrush(brush);
- }
-
- // Get/set colors
-
- Status GetCenterColor(OUT Color* color) const
- {
- ARGB argb;
-
- if (color == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- SetStatus(DllExports::GdipGetPathGradientCenterColor(
- (GpPathGradient*) nativeBrush, &argb));
-
- color->SetValue(argb);
-
- return lastResult;
- }
-
- Status SetCenterColor(IN const Color& color)
- {
- SetStatus(DllExports::GdipSetPathGradientCenterColor(
- (GpPathGradient*) nativeBrush,
- color.GetValue()));
-
- return lastResult;
- }
-
- INT GetPointCount() const
- {
- INT count;
-
- SetStatus(DllExports::GdipGetPathGradientPointCount(
- (GpPathGradient*) nativeBrush, &count));
-
- return count;
- }
-
- INT GetSurroundColorCount() const
- {
- INT count;
-
- SetStatus(DllExports::GdipGetPathGradientSurroundColorCount(
- (GpPathGradient*) nativeBrush, &count));
-
- return count;
- }
-
- Status GetSurroundColors(OUT Color* colors,
- IN OUT INT* count) const
- {
- if(colors == NULL || count == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- INT count1;
-
- SetStatus(DllExports::GdipGetPathGradientSurroundColorCount(
- (GpPathGradient*) nativeBrush, &count1));
-
- if(lastResult != Ok)
- return lastResult;
-
- if((*count < count1) || (count1 <= 0))
- return SetStatus(InsufficientBuffer);
-
- ARGB* argbs = (ARGB*) new ARGB[count1];
- if(argbs == NULL)
- return SetStatus(OutOfMemory);
-
- SetStatus(DllExports::GdipGetPathGradientSurroundColorsWithCount(
- (GpPathGradient*)nativeBrush, argbs, &count1));
-
- if(lastResult == Ok)
- {
- for(INT i = 0; i < count1; i++)
- {
- colors[i].SetValue(argbs[i]);
- }
- *count = count1;
- }
-
- delete [] argbs;
- return lastResult;
- }
-
- Status SetSurroundColors(IN const Color* colors,
- IN OUT INT* count)
- {
- if(colors == NULL || count == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- INT count1 = GetPointCount();
-
- if((*count > count1) || (count1 <= 0))
- return SetStatus(InvalidParameter);
-
- count1 = *count;
-
- ARGB* argbs = (ARGB*) new ARGB[count1];
- if(argbs == NULL)
- return SetStatus(OutOfMemory);
-
- for(INT i = 0; i < count1; i++)
- {
- argbs[i] = colors[i].GetValue();
- }
-
- SetStatus(DllExports::GdipSetPathGradientSurroundColorsWithCount(
- (GpPathGradient*)nativeBrush, argbs, &count1));
-
- if(lastResult == Ok)
- *count = count1;
-
- delete [] argbs;
-
- return lastResult;
- }
-
- Status GetGraphicsPath(OUT GraphicsPath* path) const
- {
- if(path == NULL)
- return SetStatus(InvalidParameter);
-
- return SetStatus(DllExports::GdipGetPathGradientPath(
- (GpPathGradient*)nativeBrush, path->nativePath));
- }
-
- Status SetGraphicsPath(IN const GraphicsPath* path)
- {
- if(path == NULL)
- return SetStatus(InvalidParameter);
-
- return SetStatus(DllExports::GdipSetPathGradientPath(
- (GpPathGradient*)nativeBrush, path->nativePath));
- }
-
- Status GetCenterPoint(OUT PointF* point) const
- {
- return SetStatus(DllExports::GdipGetPathGradientCenterPoint(
- (GpPathGradient*)nativeBrush,
- point));
- }
-
-
- Status GetCenterPoint(OUT Point* point) const
- {
- return SetStatus(DllExports::GdipGetPathGradientCenterPointI(
- (GpPathGradient*)nativeBrush,
- point));
- }
-
- Status SetCenterPoint(IN const PointF& point)
- {
- return SetStatus(DllExports::GdipSetPathGradientCenterPoint(
- (GpPathGradient*)nativeBrush,
- &point));
- }
-
- Status SetCenterPoint(IN const Point& point)
- {
- return SetStatus(DllExports::GdipSetPathGradientCenterPointI(
- (GpPathGradient*)nativeBrush,
- &point));
- }
-
- Status GetRectangle(OUT RectF* rect) const
- {
- return SetStatus(DllExports::GdipGetPathGradientRect(
- (GpPathGradient*)nativeBrush, rect));
- }
-
- Status GetRectangle(OUT Rect* rect) const
- {
- return SetStatus(DllExports::GdipGetPathGradientRectI(
- (GpPathGradient*)nativeBrush, rect));
- }
-
- // Gamma correction.
-
- Status SetGammaCorrection(IN BOOL useGammaCorrection)
- {
- return SetStatus(DllExports::GdipSetPathGradientGammaCorrection(
- (GpPathGradient*)nativeBrush, useGammaCorrection));
- }
-
- BOOL GetGammaCorrection() const
- {
- BOOL useGammaCorrection;
-
- SetStatus(DllExports::GdipGetPathGradientGammaCorrection(
- (GpPathGradient*)nativeBrush, &useGammaCorrection));
-
- return useGammaCorrection;
- }
-
- INT GetBlendCount() const
- {
- INT count = 0;
-
- SetStatus(DllExports::GdipGetPathGradientBlendCount(
- (GpPathGradient*) nativeBrush, &count));
-
- return count;
- }
-
- Status GetBlend(OUT REAL* blendFactors,
- OUT REAL* blendPositions,
- IN INT count) const
- {
- return SetStatus(DllExports::GdipGetPathGradientBlend(
- (GpPathGradient*)nativeBrush,
- blendFactors, blendPositions, count));
- }
-
- Status SetBlend(IN const REAL* blendFactors,
- IN const REAL* blendPositions,
- IN INT count)
- {
- return SetStatus(DllExports::GdipSetPathGradientBlend(
- (GpPathGradient*)nativeBrush,
- blendFactors, blendPositions, count));
- }
-
- INT GetInterpolationColorCount() const
- {
- INT count = 0;
-
- SetStatus(DllExports::GdipGetPathGradientPresetBlendCount(
- (GpPathGradient*) nativeBrush, &count));
-
- return count;
- }
-
- Status SetInterpolationColors(IN const Color* presetColors,
- IN const REAL* blendPositions,
- IN INT count)
- {
- if ((count <= 0) || !presetColors)
- {
- return SetStatus(InvalidParameter);
- }
-
- ARGB* argbs = (ARGB*) new ARGB[count];
- if(argbs)
- {
- for(INT i = 0; i < count; i++)
- {
- argbs[i] = presetColors[i].GetValue();
- }
-
- Status status = SetStatus(DllExports::GdipSetPathGradientPresetBlend(
- (GpPathGradient*) nativeBrush,
- argbs,
- blendPositions,
- count));
- delete[] argbs;
- return status;
- }
- else
- {
- return SetStatus(OutOfMemory);
- }
- }
-
- Status GetInterpolationColors(OUT Color* presetColors,
- OUT REAL* blendPositions,
- IN INT count) const
- {
- if ((count <= 0) || !presetColors)
- {
- return SetStatus(InvalidParameter);
- }
-
- ARGB* argbs = (ARGB*) new ARGB[count];
-
- if (!argbs)
- {
- return SetStatus(OutOfMemory);
- }
-
- GpStatus status = SetStatus(DllExports::GdipGetPathGradientPresetBlend(
- (GpPathGradient*)nativeBrush,
- argbs,
- blendPositions,
- count));
-
- for(INT i = 0; i < count; i++)
- {
- presetColors[i] = Color(argbs[i]);
- }
- delete [] argbs;
-
- return status;
- }
-
- Status SetBlendBellShape(IN REAL focus,
- IN REAL scale = 1.0)
- {
- return SetStatus(DllExports::GdipSetPathGradientSigmaBlend(
- (GpPathGradient*)nativeBrush, focus, scale));
- }
-
- #ifdef DCR_USE_NEW_145135
- Status SetBlendTriangularShape(
- IN REAL focus,
- IN REAL scale = 1.0
- )
- #else
- Status SetBlendTrianglarShape(IN REAL focus,
- IN REAL scale = 1.0)
- #endif
- {
- return SetStatus(DllExports::GdipSetPathGradientLinearBlend(
- (GpPathGradient*)nativeBrush, focus, scale));
- }
-
- /**
- * Get/set brush transform
- */
- Status GetTransform(OUT Matrix *matrix) const
- {
- return SetStatus(DllExports::GdipGetPathGradientTransform(
- (GpPathGradient*) nativeBrush, matrix->nativeMatrix));
- }
-
- Status SetTransform(IN const Matrix* matrix)
- {
- return SetStatus(DllExports::GdipSetPathGradientTransform(
- (GpPathGradient*) nativeBrush, matrix->nativeMatrix));
- }
-
- Status ResetTransform()
- {
- return SetStatus(DllExports::GdipResetPathGradientTransform((GpPathGradient*)nativeBrush));
- }
-
- Status MultiplyTransform(IN const Matrix* matrix,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipMultiplyPathGradientTransform((GpPathGradient*)nativeBrush,
- matrix->nativeMatrix,
- order));
- }
-
- Status TranslateTransform(IN REAL dx,
- IN REAL dy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipTranslatePathGradientTransform((GpPathGradient*)nativeBrush,
- dx, dy, order));
- }
-
- Status ScaleTransform(IN REAL sx,
- IN REAL sy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipScalePathGradientTransform((GpPathGradient*)nativeBrush,
- sx, sy, order));
- }
-
- Status RotateTransform(IN REAL angle,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipRotatePathGradientTransform((GpPathGradient*)nativeBrush,
- angle, order));
- }
-
- /**
- * Get/set brush focus scales
- */
- Status GetFocusScales(OUT REAL* xScale,
- OUT REAL* yScale) const
- {
- return SetStatus(DllExports::GdipGetPathGradientFocusScales(
- (GpPathGradient*) nativeBrush, xScale, yScale));
- }
-
- Status SetFocusScales(IN REAL xScale,
- IN REAL yScale)
- {
- return SetStatus(DllExports::GdipSetPathGradientFocusScales(
- (GpPathGradient*) nativeBrush, xScale, yScale));
- }
-
- /**
- * Get/set brush wrapping mode
- */
- WrapMode GetWrapMode() const
- {
- WrapMode wrapMode;
-
- SetStatus(DllExports::GdipGetPathGradientWrapMode(
- (GpPathGradient*) nativeBrush, &wrapMode));
-
- return wrapMode;
- }
-
- Status SetWrapMode(IN WrapMode wrapMode)
- {
- return SetStatus(DllExports::GdipSetPathGradientWrapMode(
- (GpPathGradient*) nativeBrush, wrapMode));
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- PathGradientBrush(const PathGradientBrush &);
- PathGradientBrush& operator=(const PathGradientBrush &);
-
-#endif
-
-protected:
-
- PathGradientBrush()
- {
- }
-};
-
-
-#endif // !_GRAPHICSPATH_HPP
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusPath.h
+*
+* Abstract:
+*
+* Path related declarations
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSPATH_H
+#define _GDIPLUSPATH_H
+
+class GraphicsPath : public GdiplusBase
+{
+public:
+ friend class Graphics;
+ friend class Region;
+ friend class PathGradientBrush;
+ friend class GraphicsPathIterator;
+ friend class CustomLineCap;
+
+ // Path constructors
+
+ GraphicsPath(IN FillMode fillMode = FillModeAlternate)
+ {
+ nativePath = NULL;
+ lastResult = DllExports::GdipCreatePath(fillMode, &nativePath);
+ }
+
+ GraphicsPath(IN const PointF* points,
+ IN const BYTE* types,
+ IN INT count,
+ IN FillMode fillMode = FillModeAlternate)
+ {
+ nativePath = NULL;
+ lastResult = DllExports::GdipCreatePath2(points,
+ types,
+ count,
+ fillMode,
+ &nativePath);
+ }
+
+ GraphicsPath(IN const Point* points,
+ IN const BYTE* types,
+ IN INT count,
+ IN FillMode fillMode = FillModeAlternate)
+ {
+ nativePath = NULL;
+ lastResult = DllExports::GdipCreatePath2I(points,
+ types,
+ count,
+ fillMode,
+ &nativePath);
+ }
+
+ ~GraphicsPath()
+ {
+ DllExports::GdipDeletePath(nativePath);
+ }
+
+ /**
+ * Make a copy of the current path object
+ */
+ GraphicsPath* Clone() const
+ {
+ GpPath *clonepath = NULL;
+
+ SetStatus(DllExports::GdipClonePath(nativePath, &clonepath));
+
+ return new GraphicsPath(clonepath);
+ }
+
+ /**
+ * Reset the path object to empty (and fill mode to FillModeAlternate)
+ */
+ Status Reset()
+ {
+ return SetStatus(DllExports::GdipResetPath(nativePath));
+ }
+
+ /**
+ * Get path fill mode information
+ */
+ FillMode GetFillMode() const
+ {
+ FillMode fillmode = FillModeAlternate;
+
+ SetStatus(DllExports::GdipGetPathFillMode(nativePath, &fillmode));
+
+ return fillmode;
+ }
+
+ /**
+ * Set path fill mode information
+ */
+ Status SetFillMode(IN FillMode fillmode)
+ {
+ return SetStatus(DllExports::GdipSetPathFillMode(nativePath, fillmode));
+ }
+
+ /**
+ * Set/get path data
+ */
+ Status GetPathData(OUT PathData* pathData) const
+ {
+ if (pathData == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ INT count = GetPointCount();
+
+ if ((count <= 0) || (pathData->Count>0 && pathData->Count<count))
+ {
+ pathData->Count = 0;
+ if (pathData->Points)
+ {
+ delete pathData->Points;
+ pathData->Points = NULL;
+ }
+
+ if (pathData->Types)
+ {
+ delete pathData->Types;
+ pathData->Types = NULL;
+ }
+
+ if (count <= 0)
+ {
+ return lastResult;
+ }
+ }
+
+ if (pathData->Count == 0)
+ {
+ pathData->Points = new PointF[count];
+ if (pathData->Points == NULL)
+ {
+ return SetStatus(OutOfMemory);
+
+ }
+ pathData->Types = new byte[count];
+ if (pathData->Types == NULL)
+ {
+ delete pathData->Points;
+ pathData->Points = NULL;
+
+ return SetStatus(OutOfMemory);
+ }
+ pathData->Count = count;
+ }
+
+ return SetStatus(DllExports::GdipGetPathData(nativePath, pathData));
+ }
+
+ /**
+ * Start/end a subpath
+ */
+ Status StartFigure()
+ {
+ return SetStatus(DllExports::GdipStartPathFigure(nativePath));
+ }
+
+ Status CloseFigure()
+ {
+ return SetStatus(DllExports::GdipClosePathFigure(nativePath));
+ }
+
+ Status CloseAllFigures()
+ {
+ return SetStatus(DllExports::GdipClosePathFigures(nativePath));
+ }
+
+ Status SetMarker()
+ {
+ return SetStatus(DllExports::GdipSetPathMarker(nativePath));
+ }
+
+ Status ClearMarkers()
+ {
+ return SetStatus(DllExports::GdipClearPathMarkers(nativePath));
+ }
+
+ Status Reverse()
+ {
+ return SetStatus(DllExports::GdipReversePath(nativePath));
+ }
+
+ Status GetLastPoint(OUT PointF* lastPoint) const
+ {
+ return SetStatus(DllExports::GdipGetPathLastPoint(nativePath, lastPoint));
+ }
+
+ /**
+ * Add lines to the path object
+ */
+ // float version
+ Status AddLine(IN const PointF& pt1,
+ IN const PointF& pt2)
+ {
+ return AddLine(pt1.X, pt1.Y, pt2.X, pt2.Y);
+ }
+
+ Status AddLine(IN REAL x1,
+ IN REAL y1,
+ IN REAL x2,
+ IN REAL y2)
+ {
+ return SetStatus(DllExports::GdipAddPathLine(nativePath, x1, y1, x2, y2));
+ }
+
+ Status AddLines(IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathLine2(nativePath, points, count));
+ }
+
+ // integer version
+ Status AddLine(IN const Point& pt1,
+ IN const Point& pt2)
+ {
+ return AddLine(pt1.X,
+ pt1.Y,
+ pt2.X,
+ pt2.Y);
+ }
+
+ Status AddLine(IN INT x1,
+ IN INT y1,
+ IN INT x2,
+ IN INT y2)
+ {
+ return SetStatus(DllExports::GdipAddPathLineI(nativePath,
+ x1,
+ y1,
+ x2,
+ y2));
+ }
+
+ Status AddLines(IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathLine2I(nativePath,
+ points,
+ count));
+ }
+
+ /**
+ * Add an arc to the path object
+ */
+ // float version
+ Status AddArc(IN const RectF& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return AddArc(rect.X, rect.Y, rect.Width, rect.Height,
+ startAngle, sweepAngle);
+ }
+
+ Status AddArc(IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipAddPathArc(nativePath, x, y, width, height,
+ startAngle, sweepAngle));
+ }
+
+ // integer version
+ Status AddArc(IN const Rect& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return AddArc(rect.X, rect.Y, rect.Width, rect.Height,
+ startAngle, sweepAngle);
+ }
+
+ Status AddArc(IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipAddPathArcI(nativePath,
+ x,
+ y,
+ width,
+ height,
+ startAngle,
+ sweepAngle));
+ }
+
+ /**
+ * Add Bezier curves to the path object
+ */
+ // float version
+ Status AddBezier(IN const PointF& pt1,
+ IN const PointF& pt2,
+ IN const PointF& pt3,
+ IN const PointF& pt4)
+ {
+ return AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X,
+ pt4.Y);
+ }
+
+ Status AddBezier(IN REAL x1,
+ IN REAL y1,
+ IN REAL x2,
+ IN REAL y2,
+ IN REAL x3,
+ IN REAL y3,
+ IN REAL x4,
+ IN REAL y4)
+ {
+ return SetStatus(DllExports::GdipAddPathBezier(nativePath, x1, y1, x2, y2,
+ x3, y3, x4, y4));
+ }
+
+ Status AddBeziers(IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathBeziers(nativePath, points, count));
+ }
+
+ // integer version
+ Status AddBezier(IN const Point& pt1,
+ IN const Point& pt2,
+ IN const Point& pt3,
+ IN const Point& pt4)
+ {
+ return AddBezier(pt1.X, pt1.Y, pt2.X, pt2.Y, pt3.X, pt3.Y, pt4.X,
+ pt4.Y);
+ }
+
+ Status AddBezier(IN INT x1,
+ IN INT y1,
+ IN INT x2,
+ IN INT y2,
+ IN INT x3,
+ IN INT y3,
+ IN INT x4,
+ IN INT y4)
+ {
+ return SetStatus(DllExports::GdipAddPathBezierI(nativePath,
+ x1,
+ y1,
+ x2,
+ y2,
+ x3,
+ y3,
+ x4,
+ y4));
+ }
+
+ Status AddBeziers(IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathBeziersI(nativePath,
+ points,
+ count));
+ }
+
+ // float version
+ Status AddCurve(IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathCurve(nativePath,
+ points,
+ count));
+ }
+
+ Status AddCurve(IN const PointF* points,
+ IN INT count,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipAddPathCurve2(nativePath,
+ points,
+ count,
+ tension));
+ }
+
+ Status AddCurve(IN const PointF* points,
+ IN INT count,
+ IN INT offset,
+ IN INT numberOfSegments,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipAddPathCurve3(nativePath,
+ points,
+ count,
+ offset,
+ numberOfSegments,
+ tension));
+ }
+
+ // integer version
+ Status AddCurve(IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathCurveI(nativePath,
+ points,
+ count));
+ }
+
+ Status AddCurve(IN const Point* points,
+ IN INT count,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipAddPathCurve2I(nativePath,
+ points,
+ count,
+ tension));
+ }
+
+ Status AddCurve(IN const Point* points,
+ IN INT count,
+ IN INT offset,
+ IN INT numberOfSegments,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipAddPathCurve3I(nativePath,
+ points,
+ count,
+ offset,
+ numberOfSegments,
+ tension));
+ }
+
+ // float version
+ Status AddClosedCurve(IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathClosedCurve(nativePath,
+ points,
+ count));
+ }
+
+ Status AddClosedCurve(IN const PointF* points,
+ IN INT count,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipAddPathClosedCurve2(nativePath,
+ points,
+ count,
+ tension));
+ }
+
+ // integer version
+ Status AddClosedCurve(IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathClosedCurveI(nativePath,
+ points,
+ count));
+ }
+
+
+ Status AddClosedCurve(IN const Point* points,
+ IN INT count,
+ IN REAL tension)
+ {
+ return SetStatus(DllExports::GdipAddPathClosedCurve2I(nativePath,
+ points,
+ count,
+ tension));
+ }
+
+
+ /**
+ * Add closed shapes to the path object
+ */
+
+ // float version
+ Status AddRectangle(IN const RectF& rect)
+ {
+ return SetStatus(DllExports::GdipAddPathRectangle(nativePath,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height));
+ }
+
+ Status AddRectangles(IN const RectF* rects,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathRectangles(nativePath,
+ rects,
+ count));
+ }
+
+ // integer version
+ Status AddRectangle(IN const Rect& rect)
+ {
+ return SetStatus(DllExports::GdipAddPathRectangleI(nativePath,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height));
+ }
+
+ Status AddRectangles(IN const Rect* rects, INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathRectanglesI(nativePath,
+ rects,
+ count));
+ }
+
+ // float version
+ Status AddEllipse(IN const RectF& rect)
+ {
+ return AddEllipse(rect.X, rect.Y, rect.Width, rect.Height);
+ }
+
+ Status AddEllipse(IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height)
+ {
+ return SetStatus(DllExports::GdipAddPathEllipse(nativePath,
+ x,
+ y,
+ width,
+ height));
+ }
+
+ // integer version
+ Status AddEllipse(IN const Rect& rect)
+ {
+ return AddEllipse(rect.X, rect.Y, rect.Width, rect.Height);
+ }
+
+ Status AddEllipse(IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height)
+ {
+ return SetStatus(DllExports::GdipAddPathEllipseI(nativePath,
+ x,
+ y,
+ width,
+ height));
+ }
+
+ // float version
+ Status AddPie(IN const RectF& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return AddPie(rect.X, rect.Y, rect.Width, rect.Height, startAngle,
+ sweepAngle);
+ }
+
+ Status AddPie(IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipAddPathPie(nativePath, x, y, width, height,
+ startAngle, sweepAngle));
+ }
+
+ // integer version
+ Status AddPie(IN const Rect& rect,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return AddPie(rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height,
+ startAngle,
+ sweepAngle);
+ }
+
+ Status AddPie(IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height,
+ IN REAL startAngle,
+ IN REAL sweepAngle)
+ {
+ return SetStatus(DllExports::GdipAddPathPieI(nativePath,
+ x,
+ y,
+ width,
+ height,
+ startAngle,
+ sweepAngle));
+ }
+
+ // float version
+ Status AddPolygon(IN const PointF* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathPolygon(nativePath, points, count));
+ }
+
+ // integer version
+ Status AddPolygon(IN const Point* points,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipAddPathPolygonI(nativePath, points, count));
+ }
+
+ Status AddPath(IN const GraphicsPath* addingPath,
+ IN BOOL connect)
+ {
+ GpPath* nativePath2 = NULL;
+ if(addingPath)
+ nativePath2 = addingPath->nativePath;
+
+ return SetStatus(DllExports::GdipAddPathPath(nativePath, nativePath2, connect));
+ }
+
+ // AddString point version
+
+ Status AddString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const FontFamily *family,
+ IN INT style,
+ IN REAL emSize, // In world units
+ IN const PointF &origin,
+ IN const StringFormat *format
+ )
+ {
+ RectF rect(origin.X, origin.Y, 0.0f, 0.0f);
+
+ return SetStatus(DllExports::GdipAddPathString(
+ nativePath,
+ string,
+ length,
+ family ? family->nativeFamily : NULL,
+ style,
+ emSize,
+ &rect,
+ format ? format->nativeFormat : NULL
+ ));
+ }
+
+ // AddString rectangle version
+
+ Status AddString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const FontFamily *family,
+ IN INT style,
+ IN REAL emSize, // In world units
+ IN const RectF &layoutRect,
+ IN const StringFormat *format
+ )
+ {
+ return SetStatus(DllExports::GdipAddPathString(
+ nativePath,
+ string,
+ length,
+ family ? family->nativeFamily : NULL,
+ style,
+ emSize,
+ &layoutRect,
+ format ? format->nativeFormat : NULL
+ ));
+ }
+
+ Status AddString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const FontFamily *family,
+ IN INT style,
+ IN REAL emSize, // In world units
+ IN const Point &origin,
+ IN const StringFormat *format
+ )
+ {
+ Rect rect(origin.X, origin.Y, 0, 0);
+
+ return SetStatus(DllExports::GdipAddPathStringI(
+ nativePath,
+ string,
+ length,
+ family ? family->nativeFamily : NULL,
+ style,
+ emSize,
+ &rect,
+ format ? format->nativeFormat : NULL
+ ));
+ }
+
+ // AddString rectangle version
+
+ Status AddString(
+ IN const WCHAR *string,
+ IN INT length,
+ IN const FontFamily *family,
+ IN INT style,
+ IN REAL emSize, // In world units
+ IN const Rect &layoutRect,
+ IN const StringFormat *format
+ )
+ {
+ return SetStatus(DllExports::GdipAddPathStringI(
+ nativePath,
+ string,
+ length,
+ family ? family->nativeFamily : NULL,
+ style,
+ emSize,
+ &layoutRect,
+ format ? format->nativeFormat : NULL
+ ));
+ }
+
+ /**
+ * Transforms the path object
+ */
+ Status Transform(IN const Matrix* matrix)
+ {
+ if(matrix)
+ return SetStatus(DllExports::GdipTransformPath(nativePath, matrix->nativeMatrix));
+ else
+ return Ok; // No need to transform.
+ }
+
+ /**
+ * Get the bounds of the path object with the given transform.
+ * This is not always the tightest bounds.
+ *
+ * Defined in GdiplusGraphics.h.
+ */
+ Status GetBounds(OUT RectF* bounds,
+ IN const Matrix* matrix = NULL,
+ IN const Pen* pen = NULL) const;
+
+ // integer version (defined in GdiplusGraphics.h)
+ Status GetBounds(OUT Rect* bounds,
+ IN const Matrix* matrix = NULL,
+ IN const Pen* pen = NULL) const;
+
+ /**
+ * Flatten the path object
+ * Once this is called, the resultant path is made of line segments and
+ * the original path information is lost.
+ * When matrix = NULL, the identity matrix is assumed.
+ */
+ Status Flatten(IN const Matrix* matrix = NULL,
+ IN REAL flatness = FlatnessDefault)
+ {
+ GpMatrix* nativeMatrix = NULL;
+ if(matrix)
+ {
+ nativeMatrix = matrix->nativeMatrix;
+ }
+
+ return SetStatus(DllExports::GdipFlattenPath(
+ nativePath,
+ nativeMatrix,
+ flatness
+ ));
+ }
+
+#ifdef DCR_USE_NEW_202903
+
+ Status Widen(
+ IN const Pen* pen,
+ IN const Matrix* matrix = NULL,
+ IN REAL flatness = FlatnessDefault
+ )
+ {
+ GpMatrix* nativeMatrix = NULL;
+ if(matrix)
+ nativeMatrix = matrix->nativeMatrix;
+
+ return SetStatus(DllExports::GdipWidenPath(
+ nativePath,
+ pen->nativePen,
+ nativeMatrix,
+ flatness
+ ));
+ }
+
+#else
+
+ /**
+ * Widen the path object
+ * When removeSelfIntersects is TRUE, this returns the widened path
+ * without self intersections.
+ * When it is FALSE, it returns the widened path with selfintersections.
+ * The latter is faster and is usually safficient for filling.
+ */
+ Status Widen(IN const Pen* pen,
+ IN const Matrix* matrix = NULL,
+ IN BOOL removeSelfIntersects = TRUE)
+ {
+ GpMatrix* nativeMatrix = NULL;
+ if(matrix)
+ nativeMatrix = matrix->nativeMatrix;
+
+ return SetStatus(DllExports::GdipWidenPathWithMinimumResolutions(nativePath, pen->nativePen,
+ 0, 0, nativeMatrix, removeSelfIntersects));
+ }
+
+ /**
+ * Widen the path object
+ * This is equivalent to Widen() method except that
+ * The widths of the widened path are larger than the given
+ * minimum resolutions in x and y coordinates after the transform.
+ * This is usefull when widening a path with the limited device resolutions.
+ */
+
+ Status Widen(IN const Pen* pen,
+ IN REAL minXres,
+ IN REAL minYres,
+ IN const Matrix* matrix = NULL,
+ IN BOOL removeSelfIntersects = TRUE)
+ {
+ GpMatrix* nativeMatrix = NULL;
+ if(matrix)
+ nativeMatrix = matrix->nativeMatrix;
+
+ return SetStatus(DllExports::GdipWidenPathWithMinimumResolutions(nativePath, pen->nativePen,
+ minXres, minYres, nativeMatrix, removeSelfIntersects));
+ }
+
+#endif // DCR_USE_NEW_202903
+
+ Status Outline(
+ IN const Matrix *matrix = NULL,
+ IN REAL flatness = FlatnessDefault
+ )
+ {
+ GpMatrix* nativeMatrix = NULL;
+ if(matrix)
+ {
+ nativeMatrix = matrix->nativeMatrix;
+ }
+
+ return SetStatus(DllExports::GdipWindingModeOutline(
+ nativePath, nativeMatrix, flatness
+ ));
+ }
+
+ /**
+ * Warp the path object
+ * Once this is called, the resultant path is made of line segments and
+ * the original path information is lost.
+ * When matrix = NULL, the identity matrix is assumed.
+ */
+ Status Warp(IN const PointF* destPoints,
+ IN INT count,
+ IN const RectF& srcRect,
+ IN const Matrix* matrix = NULL,
+ IN WarpMode warpMode = WarpModePerspective,
+ IN REAL flatness = FlatnessDefault)
+ {
+ GpMatrix* nativeMatrix = NULL;
+ if(matrix)
+ nativeMatrix = matrix->nativeMatrix;
+
+ return SetStatus(DllExports::GdipWarpPath(
+ nativePath,
+ nativeMatrix,
+ destPoints,
+ count,
+ srcRect.X,
+ srcRect.Y,
+ srcRect.Width,
+ srcRect.Height,
+ warpMode,
+ flatness));
+ }
+
+ /**
+ * Return the number of points in the current path
+ */
+ INT GetPointCount() const
+ {
+ INT count = 0;
+
+ SetStatus(DllExports::GdipGetPointCount(nativePath, &count));
+
+ return count;
+ }
+
+ /**
+ * Return the path point type information
+ */
+ Status GetPathTypes(OUT BYTE* types,
+ IN INT count) const
+ {
+ return SetStatus(DllExports::GdipGetPathTypes(nativePath, types, count));
+ }
+
+ /**
+ * Return the path point coordinate information
+ * @notes Should there be PathData that contains types[] and points[]
+ * for get & set purposes.
+ */
+ Status GetPathPoints(OUT PointF* points,
+ IN INT count) const
+ {
+ return SetStatus(DllExports::GdipGetPathPoints(nativePath, points, count));
+ }
+
+ // integer version
+ Status GetPathPoints(OUT Point* points,
+ IN INT count) const
+ {
+ return SetStatus(DllExports::GdipGetPathPointsI(nativePath, points, count));
+ }
+
+ Status GetLastStatus() const
+ {
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+ }
+
+ /**
+ * Hit testing operations
+ *
+ * inline implementation is in gdiplusgraphics.h.
+ */
+
+ BOOL IsVisible(IN const PointF& point,
+ IN const Graphics* g = NULL) const
+ {
+ return IsVisible(point.X, point.Y, g);
+ }
+
+ BOOL IsVisible(IN REAL x,
+ IN REAL y,
+ IN const Graphics* g = NULL) const;
+
+ BOOL IsVisible(IN const Point& point,
+ IN const Graphics* g = NULL) const
+ {
+ return IsVisible(point.X, point.Y, g);
+ }
+
+ BOOL IsVisible(IN INT x,
+ IN INT y,
+ IN const Graphics* g = NULL) const;
+
+ BOOL IsOutlineVisible(IN const PointF& point,
+ IN const Pen* pen,
+ IN const Graphics* g = NULL) const
+ {
+ return IsOutlineVisible(point.X, point.Y, pen, g);
+ }
+
+ BOOL IsOutlineVisible(IN REAL x,
+ IN REAL y,
+ IN const Pen* pen,
+ IN const Graphics* g = NULL) const;
+
+ BOOL IsOutlineVisible(IN const Point& point,
+ IN const Pen* pen,
+ IN const Graphics* g = NULL) const
+ {
+ return IsOutlineVisible(point.X, point.Y, pen, g);
+ }
+
+ BOOL IsOutlineVisible(IN INT x,
+ IN INT y,
+ IN const Pen* pen,
+ IN const Graphics* g = NULL) const;
+
+protected:
+
+ GraphicsPath(const GraphicsPath& path)
+ {
+ GpPath *clonepath = NULL;
+ SetStatus(DllExports::GdipClonePath(path.nativePath, &clonepath));
+ SetNativePath(clonepath);
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ GraphicsPath& operator=(const GraphicsPath &);
+protected:
+
+#else
+
+ GraphicsPath& operator=(const GraphicsPath& path)
+ {
+ path;
+ SetStatus(NotImplemented);
+ return *this;
+ }
+
+#endif
+
+ GraphicsPath(GpPath* nativePath)
+ {
+ lastResult = Ok;
+ SetNativePath(nativePath);
+ }
+
+ VOID SetNativePath(GpPath *nativePath)
+ {
+ this->nativePath = nativePath;
+ }
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+protected:
+ GpPath* nativePath;
+ mutable Status lastResult;
+};
+
+
+//--------------------------------------------------------------------------
+// GraphisPathIterator class
+//--------------------------------------------------------------------------
+
+class GraphicsPathIterator : public GdiplusBase
+{
+public:
+
+ GraphicsPathIterator(IN const GraphicsPath* path)
+ {
+ GpPath* nativePath = NULL;
+ if(path)
+ nativePath = path->nativePath;
+
+ GpPathIterator *iter = NULL;
+ lastResult = DllExports::GdipCreatePathIter(&iter, nativePath);
+ SetNativeIterator(iter);
+ }
+
+ ~GraphicsPathIterator()
+ {
+ DllExports::GdipDeletePathIter(nativeIterator);
+ }
+
+
+ INT NextSubpath(OUT INT* startIndex,
+ OUT INT* endIndex,
+ OUT BOOL* isClosed)
+ {
+ INT resultCount;
+
+ SetStatus(DllExports::GdipPathIterNextSubpath(nativeIterator,
+ &resultCount, startIndex, endIndex, isClosed));
+
+ return resultCount;
+ }
+
+
+ INT NextSubpath(IN const GraphicsPath* path,
+ OUT BOOL* isClosed)
+ {
+ GpPath* nativePath = NULL;
+
+ INT resultCount;
+
+ if(path)
+ nativePath= path->nativePath;
+
+ SetStatus(DllExports::GdipPathIterNextSubpathPath(nativeIterator,
+ &resultCount, nativePath, isClosed));
+
+ return resultCount;
+ }
+
+ INT NextPathType(OUT BYTE* pathType,
+ OUT INT* startIndex,
+ OUT INT* endIndex)
+ {
+ INT resultCount;
+
+ SetStatus(DllExports::GdipPathIterNextPathType(nativeIterator,
+ &resultCount, pathType, startIndex, endIndex));
+
+ return resultCount;
+ }
+
+ INT NextMarker(OUT INT* startIndex,
+ OUT INT* endIndex)
+ {
+ INT resultCount;
+
+ SetStatus(DllExports::GdipPathIterNextMarker(nativeIterator,
+ &resultCount, startIndex, endIndex));
+
+ return resultCount;
+ }
+
+
+ INT NextMarker(IN const GraphicsPath* path)
+ {
+ GpPath* nativePath = NULL;
+
+ INT resultCount;
+
+ if(path)
+ nativePath= path->nativePath;
+
+ SetStatus(DllExports::GdipPathIterNextMarkerPath(nativeIterator,
+ &resultCount, nativePath));
+
+ return resultCount;
+ }
+
+ INT GetCount() const
+ {
+ INT resultCount;
+
+ SetStatus(DllExports::GdipPathIterGetCount(nativeIterator, &resultCount));
+
+ return resultCount;
+ }
+
+ INT GetSubpathCount() const
+ {
+ INT resultCount;
+
+ SetStatus(DllExports::GdipPathIterGetSubpathCount(nativeIterator, &resultCount));
+
+ return resultCount;
+ }
+
+ BOOL HasCurve() const
+ {
+ BOOL hasCurve;
+
+ SetStatus(DllExports::GdipPathIterHasCurve(nativeIterator, &hasCurve));
+
+ return hasCurve;
+ }
+
+ VOID Rewind()
+ {
+ SetStatus(DllExports::GdipPathIterRewind(nativeIterator));
+ }
+
+ INT Enumerate(OUT PointF *points,
+ OUT BYTE *types,
+ IN INT count)
+ {
+ INT resultCount;
+
+ SetStatus(DllExports::GdipPathIterEnumerate(nativeIterator,
+ &resultCount, points, types, count));
+
+ return resultCount;
+ }
+
+ INT CopyData(OUT PointF* points,
+ OUT BYTE* types,
+ IN INT startIndex,
+ IN INT endIndex)
+ {
+ INT resultCount;
+
+ SetStatus(DllExports::GdipPathIterCopyData(nativeIterator,
+ &resultCount, points, types, startIndex, endIndex));
+
+ return resultCount;
+ }
+
+ Status GetLastStatus() const
+ {
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ GraphicsPathIterator(const GraphicsPathIterator &);
+ GraphicsPathIterator& operator=(const GraphicsPathIterator &);
+
+#endif
+
+protected:
+ VOID SetNativeIterator(GpPathIterator *nativeIterator)
+ {
+ this->nativeIterator = nativeIterator;
+ }
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+protected:
+ GpPathIterator* nativeIterator;
+ mutable Status lastResult;
+};
+
+
+//--------------------------------------------------------------------------
+// Represent polygon gradient brush object
+//--------------------------------------------------------------------------
+
+class PathGradientBrush : public Brush
+{
+public:
+ friend class Pen;
+
+ PathGradientBrush(
+ IN const PointF* points,
+ IN INT count,
+ IN WrapMode wrapMode = WrapModeClamp)
+ {
+ GpPathGradient *brush = NULL;
+
+ lastResult = DllExports::GdipCreatePathGradient(
+ points, count,
+ wrapMode, &brush);
+ SetNativeBrush(brush);
+ }
+
+ PathGradientBrush(
+ IN const Point* points,
+ IN INT count,
+ IN WrapMode wrapMode = WrapModeClamp)
+ {
+ GpPathGradient *brush = NULL;
+
+ lastResult = DllExports::GdipCreatePathGradientI(
+ points, count,
+ wrapMode, &brush);
+
+ SetNativeBrush(brush);
+ }
+
+ PathGradientBrush(
+ IN const GraphicsPath* path
+ )
+ {
+ GpPathGradient *brush = NULL;
+
+ lastResult = DllExports::GdipCreatePathGradientFromPath(
+ path->nativePath, &brush);
+ SetNativeBrush(brush);
+ }
+
+ // Get/set colors
+
+ Status GetCenterColor(OUT Color* color) const
+ {
+ ARGB argb;
+
+ if (color == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ SetStatus(DllExports::GdipGetPathGradientCenterColor(
+ (GpPathGradient*) nativeBrush, &argb));
+
+ color->SetValue(argb);
+
+ return lastResult;
+ }
+
+ Status SetCenterColor(IN const Color& color)
+ {
+ SetStatus(DllExports::GdipSetPathGradientCenterColor(
+ (GpPathGradient*) nativeBrush,
+ color.GetValue()));
+
+ return lastResult;
+ }
+
+ INT GetPointCount() const
+ {
+ INT count;
+
+ SetStatus(DllExports::GdipGetPathGradientPointCount(
+ (GpPathGradient*) nativeBrush, &count));
+
+ return count;
+ }
+
+ INT GetSurroundColorCount() const
+ {
+ INT count;
+
+ SetStatus(DllExports::GdipGetPathGradientSurroundColorCount(
+ (GpPathGradient*) nativeBrush, &count));
+
+ return count;
+ }
+
+ Status GetSurroundColors(OUT Color* colors,
+ IN OUT INT* count) const
+ {
+ if(colors == NULL || count == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ INT count1;
+
+ SetStatus(DllExports::GdipGetPathGradientSurroundColorCount(
+ (GpPathGradient*) nativeBrush, &count1));
+
+ if(lastResult != Ok)
+ return lastResult;
+
+ if((*count < count1) || (count1 <= 0))
+ return SetStatus(InsufficientBuffer);
+
+ ARGB* argbs = (ARGB*) new ARGB[count1];
+ if(argbs == NULL)
+ return SetStatus(OutOfMemory);
+
+ SetStatus(DllExports::GdipGetPathGradientSurroundColorsWithCount(
+ (GpPathGradient*)nativeBrush, argbs, &count1));
+
+ if(lastResult == Ok)
+ {
+ for(INT i = 0; i < count1; i++)
+ {
+ colors[i].SetValue(argbs[i]);
+ }
+ *count = count1;
+ }
+
+ delete [] argbs;
+ return lastResult;
+ }
+
+ Status SetSurroundColors(IN const Color* colors,
+ IN OUT INT* count)
+ {
+ if(colors == NULL || count == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ INT count1 = GetPointCount();
+
+ if((*count > count1) || (count1 <= 0))
+ return SetStatus(InvalidParameter);
+
+ count1 = *count;
+
+ ARGB* argbs = (ARGB*) new ARGB[count1];
+ if(argbs == NULL)
+ return SetStatus(OutOfMemory);
+
+ for(INT i = 0; i < count1; i++)
+ {
+ argbs[i] = colors[i].GetValue();
+ }
+
+ SetStatus(DllExports::GdipSetPathGradientSurroundColorsWithCount(
+ (GpPathGradient*)nativeBrush, argbs, &count1));
+
+ if(lastResult == Ok)
+ *count = count1;
+
+ delete [] argbs;
+
+ return lastResult;
+ }
+
+ Status GetGraphicsPath(OUT GraphicsPath* path) const
+ {
+ if(path == NULL)
+ return SetStatus(InvalidParameter);
+
+ return SetStatus(DllExports::GdipGetPathGradientPath(
+ (GpPathGradient*)nativeBrush, path->nativePath));
+ }
+
+ Status SetGraphicsPath(IN const GraphicsPath* path)
+ {
+ if(path == NULL)
+ return SetStatus(InvalidParameter);
+
+ return SetStatus(DllExports::GdipSetPathGradientPath(
+ (GpPathGradient*)nativeBrush, path->nativePath));
+ }
+
+ Status GetCenterPoint(OUT PointF* point) const
+ {
+ return SetStatus(DllExports::GdipGetPathGradientCenterPoint(
+ (GpPathGradient*)nativeBrush,
+ point));
+ }
+
+
+ Status GetCenterPoint(OUT Point* point) const
+ {
+ return SetStatus(DllExports::GdipGetPathGradientCenterPointI(
+ (GpPathGradient*)nativeBrush,
+ point));
+ }
+
+ Status SetCenterPoint(IN const PointF& point)
+ {
+ return SetStatus(DllExports::GdipSetPathGradientCenterPoint(
+ (GpPathGradient*)nativeBrush,
+ &point));
+ }
+
+ Status SetCenterPoint(IN const Point& point)
+ {
+ return SetStatus(DllExports::GdipSetPathGradientCenterPointI(
+ (GpPathGradient*)nativeBrush,
+ &point));
+ }
+
+ Status GetRectangle(OUT RectF* rect) const
+ {
+ return SetStatus(DllExports::GdipGetPathGradientRect(
+ (GpPathGradient*)nativeBrush, rect));
+ }
+
+ Status GetRectangle(OUT Rect* rect) const
+ {
+ return SetStatus(DllExports::GdipGetPathGradientRectI(
+ (GpPathGradient*)nativeBrush, rect));
+ }
+
+ // Gamma correction.
+
+ Status SetGammaCorrection(IN BOOL useGammaCorrection)
+ {
+ return SetStatus(DllExports::GdipSetPathGradientGammaCorrection(
+ (GpPathGradient*)nativeBrush, useGammaCorrection));
+ }
+
+ BOOL GetGammaCorrection() const
+ {
+ BOOL useGammaCorrection;
+
+ SetStatus(DllExports::GdipGetPathGradientGammaCorrection(
+ (GpPathGradient*)nativeBrush, &useGammaCorrection));
+
+ return useGammaCorrection;
+ }
+
+ INT GetBlendCount() const
+ {
+ INT count = 0;
+
+ SetStatus(DllExports::GdipGetPathGradientBlendCount(
+ (GpPathGradient*) nativeBrush, &count));
+
+ return count;
+ }
+
+ Status GetBlend(OUT REAL* blendFactors,
+ OUT REAL* blendPositions,
+ IN INT count) const
+ {
+ return SetStatus(DllExports::GdipGetPathGradientBlend(
+ (GpPathGradient*)nativeBrush,
+ blendFactors, blendPositions, count));
+ }
+
+ Status SetBlend(IN const REAL* blendFactors,
+ IN const REAL* blendPositions,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipSetPathGradientBlend(
+ (GpPathGradient*)nativeBrush,
+ blendFactors, blendPositions, count));
+ }
+
+ INT GetInterpolationColorCount() const
+ {
+ INT count = 0;
+
+ SetStatus(DllExports::GdipGetPathGradientPresetBlendCount(
+ (GpPathGradient*) nativeBrush, &count));
+
+ return count;
+ }
+
+ Status SetInterpolationColors(IN const Color* presetColors,
+ IN const REAL* blendPositions,
+ IN INT count)
+ {
+ if ((count <= 0) || !presetColors)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ ARGB* argbs = (ARGB*) new ARGB[count];
+ if(argbs)
+ {
+ for(INT i = 0; i < count; i++)
+ {
+ argbs[i] = presetColors[i].GetValue();
+ }
+
+ Status status = SetStatus(DllExports::GdipSetPathGradientPresetBlend(
+ (GpPathGradient*) nativeBrush,
+ argbs,
+ blendPositions,
+ count));
+ delete[] argbs;
+ return status;
+ }
+ else
+ {
+ return SetStatus(OutOfMemory);
+ }
+ }
+
+ Status GetInterpolationColors(OUT Color* presetColors,
+ OUT REAL* blendPositions,
+ IN INT count) const
+ {
+ if ((count <= 0) || !presetColors)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ ARGB* argbs = (ARGB*) new ARGB[count];
+
+ if (!argbs)
+ {
+ return SetStatus(OutOfMemory);
+ }
+
+ GpStatus status = SetStatus(DllExports::GdipGetPathGradientPresetBlend(
+ (GpPathGradient*)nativeBrush,
+ argbs,
+ blendPositions,
+ count));
+
+ for(INT i = 0; i < count; i++)
+ {
+ presetColors[i] = Color(argbs[i]);
+ }
+ delete [] argbs;
+
+ return status;
+ }
+
+ Status SetBlendBellShape(IN REAL focus,
+ IN REAL scale = 1.0)
+ {
+ return SetStatus(DllExports::GdipSetPathGradientSigmaBlend(
+ (GpPathGradient*)nativeBrush, focus, scale));
+ }
+
+ #ifdef DCR_USE_NEW_145135
+ Status SetBlendTriangularShape(
+ IN REAL focus,
+ IN REAL scale = 1.0
+ )
+ #else
+ Status SetBlendTrianglarShape(IN REAL focus,
+ IN REAL scale = 1.0)
+ #endif
+ {
+ return SetStatus(DllExports::GdipSetPathGradientLinearBlend(
+ (GpPathGradient*)nativeBrush, focus, scale));
+ }
+
+ /**
+ * Get/set brush transform
+ */
+ Status GetTransform(OUT Matrix *matrix) const
+ {
+ return SetStatus(DllExports::GdipGetPathGradientTransform(
+ (GpPathGradient*) nativeBrush, matrix->nativeMatrix));
+ }
+
+ Status SetTransform(IN const Matrix* matrix)
+ {
+ return SetStatus(DllExports::GdipSetPathGradientTransform(
+ (GpPathGradient*) nativeBrush, matrix->nativeMatrix));
+ }
+
+ Status ResetTransform()
+ {
+ return SetStatus(DllExports::GdipResetPathGradientTransform((GpPathGradient*)nativeBrush));
+ }
+
+ Status MultiplyTransform(IN const Matrix* matrix,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipMultiplyPathGradientTransform((GpPathGradient*)nativeBrush,
+ matrix->nativeMatrix,
+ order));
+ }
+
+ Status TranslateTransform(IN REAL dx,
+ IN REAL dy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipTranslatePathGradientTransform((GpPathGradient*)nativeBrush,
+ dx, dy, order));
+ }
+
+ Status ScaleTransform(IN REAL sx,
+ IN REAL sy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipScalePathGradientTransform((GpPathGradient*)nativeBrush,
+ sx, sy, order));
+ }
+
+ Status RotateTransform(IN REAL angle,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipRotatePathGradientTransform((GpPathGradient*)nativeBrush,
+ angle, order));
+ }
+
+ /**
+ * Get/set brush focus scales
+ */
+ Status GetFocusScales(OUT REAL* xScale,
+ OUT REAL* yScale) const
+ {
+ return SetStatus(DllExports::GdipGetPathGradientFocusScales(
+ (GpPathGradient*) nativeBrush, xScale, yScale));
+ }
+
+ Status SetFocusScales(IN REAL xScale,
+ IN REAL yScale)
+ {
+ return SetStatus(DllExports::GdipSetPathGradientFocusScales(
+ (GpPathGradient*) nativeBrush, xScale, yScale));
+ }
+
+ /**
+ * Get/set brush wrapping mode
+ */
+ WrapMode GetWrapMode() const
+ {
+ WrapMode wrapMode;
+
+ SetStatus(DllExports::GdipGetPathGradientWrapMode(
+ (GpPathGradient*) nativeBrush, &wrapMode));
+
+ return wrapMode;
+ }
+
+ Status SetWrapMode(IN WrapMode wrapMode)
+ {
+ return SetStatus(DllExports::GdipSetPathGradientWrapMode(
+ (GpPathGradient*) nativeBrush, wrapMode));
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ PathGradientBrush(const PathGradientBrush &);
+ PathGradientBrush& operator=(const PathGradientBrush &);
+
+#endif
+
+protected:
+
+ PathGradientBrush()
+ {
+ }
+};
+
+
+#endif // !_GRAPHICSPATH_HPP
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusPen.h b/core/src/fxge/Microsoft SDK/include/GdiPlusPen.h
index 20653db36e..c5776ab639 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusPen.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusPen.h
@@ -1,519 +1,519 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusPen.h
-*
-* Abstract:
-*
-* Pen API related declarations
-*
-\**************************************************************************/
-#ifndef _GDIPLUSPEN_H
-#define _GDIPLUSPEN_H
-
-//--------------------------------------------------------------------------
-// class for various pen types
-//--------------------------------------------------------------------------
-
-class Pen : public GdiplusBase
-{
-public:
- friend class GraphicsPath;
- friend class Graphics;
-
- // abstract Clone() can't be implemented here because it can't
- // new an object with pure virtual functions
-
- // Constructors
-
- Pen(IN const Color& color,
- IN REAL width = 1.0f)
- {
- Unit unit = UnitWorld;
- nativePen = NULL;
- lastResult = DllExports::GdipCreatePen1(color.GetValue(),
- width, unit, &nativePen);
- }
-
- Pen(IN const Brush* brush,
- IN REAL width = 1.0f)
- {
- Unit unit = UnitWorld;
- nativePen = NULL;
- lastResult = DllExports::GdipCreatePen2(brush->nativeBrush,
- width, unit, &nativePen);
- }
-
- ~Pen()
- {
- DllExports::GdipDeletePen(nativePen);
- }
-
- Pen* Clone() const
- {
- GpPen *clonePen = NULL;
-
- lastResult = DllExports::GdipClonePen(nativePen, &clonePen);
-
- return new Pen(clonePen, lastResult);
- }
-
- Status SetWidth(IN REAL width)
- {
- return SetStatus(DllExports::GdipSetPenWidth(nativePen, width));
- }
-
- REAL GetWidth() const
- {
- REAL width;
-
- SetStatus(DllExports::GdipGetPenWidth(nativePen, &width));
-
- return width;
- }
-
- // Set/get line caps: start, end, and dash
-
- // Line cap and join APIs by using LineCap and LineJoin enums.
-
- #ifdef DCR_USE_NEW_197819
- Status SetLineCap(IN LineCap startCap,
- IN LineCap endCap,
- IN DashCap dashCap)
- {
- return SetStatus(DllExports::GdipSetPenLineCap197819(nativePen,
- startCap, endCap, dashCap));
- }
- #else
- Status SetLineCap(IN LineCap startCap,
- IN LineCap endCap,
- IN LineCap dashCap)
- {
- return SetStatus(DllExports::GdipSetPenLineCap(nativePen,
- startCap, endCap, dashCap));
- }
- #endif // DCR_USE_NEW_197819
-
- Status SetStartCap(IN LineCap startCap)
- {
- return SetStatus(DllExports::GdipSetPenStartCap(nativePen, startCap));
- }
-
- Status SetEndCap(IN LineCap endCap)
- {
- return SetStatus(DllExports::GdipSetPenEndCap(nativePen, endCap));
- }
-
- #ifdef DCR_USE_NEW_197819
- Status SetDashCap(IN DashCap dashCap)
- {
- return SetStatus(DllExports::GdipSetPenDashCap197819(nativePen,
- dashCap));
- }
- #else
- Status SetDashCap(IN LineCap dashCap)
- {
- return SetStatus(DllExports::GdipSetPenDashCap(nativePen, dashCap));
- }
- #endif // DCR_USE_NEW_197819
-
- LineCap GetStartCap() const
- {
- LineCap startCap;
-
- SetStatus(DllExports::GdipGetPenStartCap(nativePen, &startCap));
-
- return startCap;
- }
-
- LineCap GetEndCap() const
- {
- LineCap endCap;
-
- SetStatus(DllExports::GdipGetPenEndCap(nativePen, &endCap));
-
- return endCap;
- }
-
- #ifdef DCR_USE_NEW_197819
- DashCap GetDashCap() const
- {
- DashCap dashCap;
-
- SetStatus(DllExports::GdipGetPenDashCap197819(nativePen,
- &dashCap));
-
- return dashCap;
- }
- #else
- LineCap GetDashCap() const
- {
- LineCap dashCap;
-
- SetStatus(DllExports::GdipGetPenDashCap(nativePen, &dashCap));
-
- return dashCap;
- }
- #endif // DCR_USE_NEW_197819
-
-
- // Set/get line join
-
- Status SetLineJoin(IN LineJoin lineJoin)
- {
- return SetStatus(DllExports::GdipSetPenLineJoin(nativePen, lineJoin));
- }
-
- LineJoin GetLineJoin() const
- {
- LineJoin lineJoin;
-
- SetStatus(DllExports::GdipGetPenLineJoin(nativePen, &lineJoin));
-
- return lineJoin;
- }
-
- Status SetCustomStartCap(IN const CustomLineCap* customCap)
- {
- GpCustomLineCap* nativeCap = NULL;
- if(customCap)
- nativeCap = customCap->nativeCap;
-
- return SetStatus(DllExports::GdipSetPenCustomStartCap(nativePen, nativeCap));
- }
-
- Status GetCustomStartCap(OUT CustomLineCap* customCap) const
- {
- if(!customCap)
- return SetStatus(InvalidParameter);
-
- return SetStatus(DllExports::GdipGetPenCustomStartCap(nativePen, &(customCap->nativeCap)));
- }
-
- Status SetCustomEndCap(IN const CustomLineCap* customCap)
- {
- GpCustomLineCap* nativeCap = NULL;
- if(customCap)
- nativeCap = customCap->nativeCap;
-
- return SetStatus(DllExports::GdipSetPenCustomEndCap(nativePen, nativeCap));
- }
-
- Status GetCustomEndCap(OUT CustomLineCap* customCap) const
- {
- if(!customCap)
- return SetStatus(InvalidParameter);
-
- return SetStatus(DllExports::GdipGetPenCustomEndCap(nativePen, &(customCap->nativeCap)));
- }
-
- Status SetMiterLimit(IN REAL miterLimit)
- {
- return SetStatus(DllExports::GdipSetPenMiterLimit(nativePen, miterLimit));
- }
-
- REAL GetMiterLimit() const
- {
- REAL miterLimit;
-
- SetStatus(DllExports::GdipGetPenMiterLimit(nativePen, &miterLimit));
-
- return miterLimit;
- }
-
- // Set/get pen mode
- Status SetAlignment(IN PenAlignment penAlignment)
- {
- return SetStatus(DllExports::GdipSetPenMode(nativePen, penAlignment));
- }
-
- PenAlignment GetAlignment() const
- {
- PenAlignment penAlignment;
-
- SetStatus(DllExports::GdipGetPenMode(nativePen, &penAlignment));
-
- return penAlignment;
- }
-
- // Set/get pen transform
- Status SetTransform(IN const Matrix* matrix)
- {
- return SetStatus(DllExports::GdipSetPenTransform(nativePen,
- matrix->nativeMatrix));
- }
-
- Status GetTransform(OUT Matrix* matrix) const
- {
- return SetStatus(DllExports::GdipGetPenTransform(nativePen, matrix->nativeMatrix));
- }
-
- Status ResetTransform()
- {
- return SetStatus(DllExports::GdipResetPenTransform(nativePen));
- }
-
- Status MultiplyTransform(IN const Matrix* matrix,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipMultiplyPenTransform(nativePen,
- matrix->nativeMatrix,
- order));
- }
-
- Status TranslateTransform(IN REAL dx,
- IN REAL dy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipTranslatePenTransform(nativePen,
- dx, dy, order));
- }
-
- Status ScaleTransform(IN REAL sx,
- IN REAL sy,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipScalePenTransform(nativePen,
- sx, sy, order));
- }
-
- Status RotateTransform(IN REAL angle,
- IN MatrixOrder order = MatrixOrderPrepend)
- {
- return SetStatus(DllExports::GdipRotatePenTransform(nativePen,
- angle, order));
- }
-
- PenType GetPenType() const
- {
- PenType type;
- SetStatus(DllExports::GdipGetPenFillType(nativePen, &type));
-
- return type;
- }
-
- Status SetColor(IN const Color& color)
- {
- return SetStatus(DllExports::GdipSetPenColor(nativePen,
- color.GetValue()));
- }
-
- Status SetBrush(IN const Brush* brush)
- {
- return SetStatus(DllExports::GdipSetPenBrushFill(nativePen,
- brush->nativeBrush));
- }
-
- Status GetColor(OUT Color* color) const
- {
- if (color == NULL)
- {
- return SetStatus(InvalidParameter);
- }
-
- PenType type = GetPenType();
-
- if (type != PenTypeSolidColor)
- {
- return WrongState;
- }
-
- ARGB argb;
-
- SetStatus(DllExports::GdipGetPenColor(nativePen,
- &argb));
- if (lastResult == Ok)
- {
- color->SetValue(argb);
- }
-
- return lastResult;
- }
-
- Brush* GetBrush() const
- {
- PenType type = GetPenType();
-
- Brush* brush = NULL;
-
- switch(type)
- {
- case PenTypeSolidColor:
- brush = new SolidBrush();
- break;
-
- case PenTypeHatchFill:
- brush = new HatchBrush();
- break;
-
- case PenTypeTextureFill:
- brush = new TextureBrush();
- break;
-
- case PenTypePathGradient:
- brush = new Brush();
- break;
-
- case PenTypeLinearGradient:
- brush = new LinearGradientBrush();
- break;
-
- default:
- break;
- }
-
- if(brush)
- {
- GpBrush* nativeBrush;
-
- SetStatus(DllExports::GdipGetPenBrushFill(nativePen, &nativeBrush));
- brush->SetNativeBrush(nativeBrush);
- }
-
- return brush;
- }
-
- DashStyle GetDashStyle() const
- {
- DashStyle dashStyle;
-
- SetStatus(DllExports::GdipGetPenDashStyle(nativePen, &dashStyle));
-
- return dashStyle;
- }
-
- Status SetDashStyle(IN DashStyle dashStyle)
- {
- return SetStatus(DllExports::GdipSetPenDashStyle(nativePen, dashStyle));
- }
-
- REAL GetDashOffset() const
- {
- REAL dashOffset;
-
- SetStatus(DllExports::GdipGetPenDashOffset(nativePen, &dashOffset));
-
- return dashOffset;
- }
-
- Status SetDashOffset(IN REAL dashOffset)
- {
- return SetStatus(DllExports::GdipSetPenDashOffset(nativePen, dashOffset));
- }
-
- Status SetDashPattern(IN const REAL* dashArray, IN INT count)
- {
- return SetStatus(DllExports::GdipSetPenDashArray(nativePen, dashArray,
- count));
- }
-
- INT GetDashPatternCount() const
- {
- INT count = 0;
-
- SetStatus(DllExports::GdipGetPenDashCount(nativePen, &count));
-
- return count;
- }
-
- Status GetDashPattern(OUT REAL* dashArray,
- IN INT count) const
- {
- if (dashArray == NULL || count <= 0)
- return SetStatus(InvalidParameter);
-
- return SetStatus(DllExports::GdipGetPenDashArray(nativePen,
- dashArray,
- count));
- }
-
- Status SetCompoundArray(IN const REAL* compoundArray,
- IN INT count)
- {
- return SetStatus(DllExports::GdipSetPenCompoundArray(nativePen, compoundArray,
- count));
- }
-
- INT GetCompoundArrayCount() const
- {
- INT count = 0;
-
- SetStatus(DllExports::GdipGetPenCompoundCount(nativePen, &count));
-
- return count;
- }
-
- Status GetCompoundArray(OUT REAL* compoundArray,
- IN INT count) const
- {
- if (compoundArray == NULL || count <= 0)
- return SetStatus(InvalidParameter);
-
- return SetStatus(DllExports::GdipGetPenCompoundArray(nativePen,
- compoundArray,
- count));
- }
-
- Status GetLastStatus() const
- {
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
- }
-
-protected:
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- Pen(const Pen &);
- Pen& operator=(const Pen &);
-protected:
-
-#else
-
- Pen(const Pen& pen)
- {
- pen;
- SetStatus(NotImplemented);
- SetNativePen(NULL);
- }
-
- Pen& operator=(const Pen& pen)
- {
- pen;
- SetStatus(NotImplemented);
- return *this;
- }
-
-#endif
-
- Pen(GpPen* nativePen, Status status)
- {
- lastResult = status;
- SetNativePen(nativePen);
- }
-
- VOID SetNativePen(GpPen* nativePen)
- {
- this->nativePen = nativePen;
- }
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
-protected:
- GpPen* nativePen;
- mutable Status lastResult;
-};
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusPen.h
+*
+* Abstract:
+*
+* Pen API related declarations
+*
+\**************************************************************************/
+#ifndef _GDIPLUSPEN_H
+#define _GDIPLUSPEN_H
+
+//--------------------------------------------------------------------------
+// class for various pen types
+//--------------------------------------------------------------------------
+
+class Pen : public GdiplusBase
+{
+public:
+ friend class GraphicsPath;
+ friend class Graphics;
+
+ // abstract Clone() can't be implemented here because it can't
+ // new an object with pure virtual functions
+
+ // Constructors
+
+ Pen(IN const Color& color,
+ IN REAL width = 1.0f)
+ {
+ Unit unit = UnitWorld;
+ nativePen = NULL;
+ lastResult = DllExports::GdipCreatePen1(color.GetValue(),
+ width, unit, &nativePen);
+ }
+
+ Pen(IN const Brush* brush,
+ IN REAL width = 1.0f)
+ {
+ Unit unit = UnitWorld;
+ nativePen = NULL;
+ lastResult = DllExports::GdipCreatePen2(brush->nativeBrush,
+ width, unit, &nativePen);
+ }
+
+ ~Pen()
+ {
+ DllExports::GdipDeletePen(nativePen);
+ }
+
+ Pen* Clone() const
+ {
+ GpPen *clonePen = NULL;
+
+ lastResult = DllExports::GdipClonePen(nativePen, &clonePen);
+
+ return new Pen(clonePen, lastResult);
+ }
+
+ Status SetWidth(IN REAL width)
+ {
+ return SetStatus(DllExports::GdipSetPenWidth(nativePen, width));
+ }
+
+ REAL GetWidth() const
+ {
+ REAL width;
+
+ SetStatus(DllExports::GdipGetPenWidth(nativePen, &width));
+
+ return width;
+ }
+
+ // Set/get line caps: start, end, and dash
+
+ // Line cap and join APIs by using LineCap and LineJoin enums.
+
+ #ifdef DCR_USE_NEW_197819
+ Status SetLineCap(IN LineCap startCap,
+ IN LineCap endCap,
+ IN DashCap dashCap)
+ {
+ return SetStatus(DllExports::GdipSetPenLineCap197819(nativePen,
+ startCap, endCap, dashCap));
+ }
+ #else
+ Status SetLineCap(IN LineCap startCap,
+ IN LineCap endCap,
+ IN LineCap dashCap)
+ {
+ return SetStatus(DllExports::GdipSetPenLineCap(nativePen,
+ startCap, endCap, dashCap));
+ }
+ #endif // DCR_USE_NEW_197819
+
+ Status SetStartCap(IN LineCap startCap)
+ {
+ return SetStatus(DllExports::GdipSetPenStartCap(nativePen, startCap));
+ }
+
+ Status SetEndCap(IN LineCap endCap)
+ {
+ return SetStatus(DllExports::GdipSetPenEndCap(nativePen, endCap));
+ }
+
+ #ifdef DCR_USE_NEW_197819
+ Status SetDashCap(IN DashCap dashCap)
+ {
+ return SetStatus(DllExports::GdipSetPenDashCap197819(nativePen,
+ dashCap));
+ }
+ #else
+ Status SetDashCap(IN LineCap dashCap)
+ {
+ return SetStatus(DllExports::GdipSetPenDashCap(nativePen, dashCap));
+ }
+ #endif // DCR_USE_NEW_197819
+
+ LineCap GetStartCap() const
+ {
+ LineCap startCap;
+
+ SetStatus(DllExports::GdipGetPenStartCap(nativePen, &startCap));
+
+ return startCap;
+ }
+
+ LineCap GetEndCap() const
+ {
+ LineCap endCap;
+
+ SetStatus(DllExports::GdipGetPenEndCap(nativePen, &endCap));
+
+ return endCap;
+ }
+
+ #ifdef DCR_USE_NEW_197819
+ DashCap GetDashCap() const
+ {
+ DashCap dashCap;
+
+ SetStatus(DllExports::GdipGetPenDashCap197819(nativePen,
+ &dashCap));
+
+ return dashCap;
+ }
+ #else
+ LineCap GetDashCap() const
+ {
+ LineCap dashCap;
+
+ SetStatus(DllExports::GdipGetPenDashCap(nativePen, &dashCap));
+
+ return dashCap;
+ }
+ #endif // DCR_USE_NEW_197819
+
+
+ // Set/get line join
+
+ Status SetLineJoin(IN LineJoin lineJoin)
+ {
+ return SetStatus(DllExports::GdipSetPenLineJoin(nativePen, lineJoin));
+ }
+
+ LineJoin GetLineJoin() const
+ {
+ LineJoin lineJoin;
+
+ SetStatus(DllExports::GdipGetPenLineJoin(nativePen, &lineJoin));
+
+ return lineJoin;
+ }
+
+ Status SetCustomStartCap(IN const CustomLineCap* customCap)
+ {
+ GpCustomLineCap* nativeCap = NULL;
+ if(customCap)
+ nativeCap = customCap->nativeCap;
+
+ return SetStatus(DllExports::GdipSetPenCustomStartCap(nativePen, nativeCap));
+ }
+
+ Status GetCustomStartCap(OUT CustomLineCap* customCap) const
+ {
+ if(!customCap)
+ return SetStatus(InvalidParameter);
+
+ return SetStatus(DllExports::GdipGetPenCustomStartCap(nativePen, &(customCap->nativeCap)));
+ }
+
+ Status SetCustomEndCap(IN const CustomLineCap* customCap)
+ {
+ GpCustomLineCap* nativeCap = NULL;
+ if(customCap)
+ nativeCap = customCap->nativeCap;
+
+ return SetStatus(DllExports::GdipSetPenCustomEndCap(nativePen, nativeCap));
+ }
+
+ Status GetCustomEndCap(OUT CustomLineCap* customCap) const
+ {
+ if(!customCap)
+ return SetStatus(InvalidParameter);
+
+ return SetStatus(DllExports::GdipGetPenCustomEndCap(nativePen, &(customCap->nativeCap)));
+ }
+
+ Status SetMiterLimit(IN REAL miterLimit)
+ {
+ return SetStatus(DllExports::GdipSetPenMiterLimit(nativePen, miterLimit));
+ }
+
+ REAL GetMiterLimit() const
+ {
+ REAL miterLimit;
+
+ SetStatus(DllExports::GdipGetPenMiterLimit(nativePen, &miterLimit));
+
+ return miterLimit;
+ }
+
+ // Set/get pen mode
+ Status SetAlignment(IN PenAlignment penAlignment)
+ {
+ return SetStatus(DllExports::GdipSetPenMode(nativePen, penAlignment));
+ }
+
+ PenAlignment GetAlignment() const
+ {
+ PenAlignment penAlignment;
+
+ SetStatus(DllExports::GdipGetPenMode(nativePen, &penAlignment));
+
+ return penAlignment;
+ }
+
+ // Set/get pen transform
+ Status SetTransform(IN const Matrix* matrix)
+ {
+ return SetStatus(DllExports::GdipSetPenTransform(nativePen,
+ matrix->nativeMatrix));
+ }
+
+ Status GetTransform(OUT Matrix* matrix) const
+ {
+ return SetStatus(DllExports::GdipGetPenTransform(nativePen, matrix->nativeMatrix));
+ }
+
+ Status ResetTransform()
+ {
+ return SetStatus(DllExports::GdipResetPenTransform(nativePen));
+ }
+
+ Status MultiplyTransform(IN const Matrix* matrix,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipMultiplyPenTransform(nativePen,
+ matrix->nativeMatrix,
+ order));
+ }
+
+ Status TranslateTransform(IN REAL dx,
+ IN REAL dy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipTranslatePenTransform(nativePen,
+ dx, dy, order));
+ }
+
+ Status ScaleTransform(IN REAL sx,
+ IN REAL sy,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipScalePenTransform(nativePen,
+ sx, sy, order));
+ }
+
+ Status RotateTransform(IN REAL angle,
+ IN MatrixOrder order = MatrixOrderPrepend)
+ {
+ return SetStatus(DllExports::GdipRotatePenTransform(nativePen,
+ angle, order));
+ }
+
+ PenType GetPenType() const
+ {
+ PenType type;
+ SetStatus(DllExports::GdipGetPenFillType(nativePen, &type));
+
+ return type;
+ }
+
+ Status SetColor(IN const Color& color)
+ {
+ return SetStatus(DllExports::GdipSetPenColor(nativePen,
+ color.GetValue()));
+ }
+
+ Status SetBrush(IN const Brush* brush)
+ {
+ return SetStatus(DllExports::GdipSetPenBrushFill(nativePen,
+ brush->nativeBrush));
+ }
+
+ Status GetColor(OUT Color* color) const
+ {
+ if (color == NULL)
+ {
+ return SetStatus(InvalidParameter);
+ }
+
+ PenType type = GetPenType();
+
+ if (type != PenTypeSolidColor)
+ {
+ return WrongState;
+ }
+
+ ARGB argb;
+
+ SetStatus(DllExports::GdipGetPenColor(nativePen,
+ &argb));
+ if (lastResult == Ok)
+ {
+ color->SetValue(argb);
+ }
+
+ return lastResult;
+ }
+
+ Brush* GetBrush() const
+ {
+ PenType type = GetPenType();
+
+ Brush* brush = NULL;
+
+ switch(type)
+ {
+ case PenTypeSolidColor:
+ brush = new SolidBrush();
+ break;
+
+ case PenTypeHatchFill:
+ brush = new HatchBrush();
+ break;
+
+ case PenTypeTextureFill:
+ brush = new TextureBrush();
+ break;
+
+ case PenTypePathGradient:
+ brush = new Brush();
+ break;
+
+ case PenTypeLinearGradient:
+ brush = new LinearGradientBrush();
+ break;
+
+ default:
+ break;
+ }
+
+ if(brush)
+ {
+ GpBrush* nativeBrush;
+
+ SetStatus(DllExports::GdipGetPenBrushFill(nativePen, &nativeBrush));
+ brush->SetNativeBrush(nativeBrush);
+ }
+
+ return brush;
+ }
+
+ DashStyle GetDashStyle() const
+ {
+ DashStyle dashStyle;
+
+ SetStatus(DllExports::GdipGetPenDashStyle(nativePen, &dashStyle));
+
+ return dashStyle;
+ }
+
+ Status SetDashStyle(IN DashStyle dashStyle)
+ {
+ return SetStatus(DllExports::GdipSetPenDashStyle(nativePen, dashStyle));
+ }
+
+ REAL GetDashOffset() const
+ {
+ REAL dashOffset;
+
+ SetStatus(DllExports::GdipGetPenDashOffset(nativePen, &dashOffset));
+
+ return dashOffset;
+ }
+
+ Status SetDashOffset(IN REAL dashOffset)
+ {
+ return SetStatus(DllExports::GdipSetPenDashOffset(nativePen, dashOffset));
+ }
+
+ Status SetDashPattern(IN const REAL* dashArray, IN INT count)
+ {
+ return SetStatus(DllExports::GdipSetPenDashArray(nativePen, dashArray,
+ count));
+ }
+
+ INT GetDashPatternCount() const
+ {
+ INT count = 0;
+
+ SetStatus(DllExports::GdipGetPenDashCount(nativePen, &count));
+
+ return count;
+ }
+
+ Status GetDashPattern(OUT REAL* dashArray,
+ IN INT count) const
+ {
+ if (dashArray == NULL || count <= 0)
+ return SetStatus(InvalidParameter);
+
+ return SetStatus(DllExports::GdipGetPenDashArray(nativePen,
+ dashArray,
+ count));
+ }
+
+ Status SetCompoundArray(IN const REAL* compoundArray,
+ IN INT count)
+ {
+ return SetStatus(DllExports::GdipSetPenCompoundArray(nativePen, compoundArray,
+ count));
+ }
+
+ INT GetCompoundArrayCount() const
+ {
+ INT count = 0;
+
+ SetStatus(DllExports::GdipGetPenCompoundCount(nativePen, &count));
+
+ return count;
+ }
+
+ Status GetCompoundArray(OUT REAL* compoundArray,
+ IN INT count) const
+ {
+ if (compoundArray == NULL || count <= 0)
+ return SetStatus(InvalidParameter);
+
+ return SetStatus(DllExports::GdipGetPenCompoundArray(nativePen,
+ compoundArray,
+ count));
+ }
+
+ Status GetLastStatus() const
+ {
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+ }
+
+protected:
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ Pen(const Pen &);
+ Pen& operator=(const Pen &);
+protected:
+
+#else
+
+ Pen(const Pen& pen)
+ {
+ pen;
+ SetStatus(NotImplemented);
+ SetNativePen(NULL);
+ }
+
+ Pen& operator=(const Pen& pen)
+ {
+ pen;
+ SetStatus(NotImplemented);
+ return *this;
+ }
+
+#endif
+
+ Pen(GpPen* nativePen, Status status)
+ {
+ lastResult = status;
+ SetNativePen(nativePen);
+ }
+
+ VOID SetNativePen(GpPen* nativePen)
+ {
+ this->nativePen = nativePen;
+ }
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+protected:
+ GpPen* nativePen;
+ mutable Status lastResult;
+};
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusPixelFormats.h b/core/src/fxge/Microsoft SDK/include/GdiPlusPixelFormats.h
index f9dc5991d4..68b7084074 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusPixelFormats.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusPixelFormats.h
@@ -1,201 +1,201 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* Gdiplus pixel formats
-*
-* Abstract:
-*
-* Definitions for color types, palettes, pixel format IDs.
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSPIXELFORMATS_H
-#define _GDIPLUSPIXELFORMATS_H
-
-/*
- * 32-bit and 64-bit ARGB pixel value
- */
-
-typedef DWORD ARGB;
-typedef DWORDLONG ARGB64;
-
-#define ALPHA_SHIFT 24
-#define RED_SHIFT 16
-#define GREEN_SHIFT 8
-#define BLUE_SHIFT 0
-#define ALPHA_MASK ((ARGB) 0xff << ALPHA_SHIFT)
-
-/*
- * In-memory pixel data formats:
- * bits 0-7 = format index
- * bits 8-15 = pixel size (in bits)
- * bits 16-23 = flags
- * bits 24-31 = reserved
- */
-
-#ifndef DCR_USE_NEW_105760
-
-enum PixelFormat
-{
- PixelFormatIndexed = 0x00010000, // Indexes into a palette
- PixelFormatGDI = 0x00020000, // Is a GDI-supported format
- PixelFormatAlpha = 0x00040000, // Has an alpha component
- PixelFormatPAlpha = 0x00080000, // Uses pre-multiplied alpha
- PixelFormatExtended = 0x00100000, // Uses extended color (16 bits per channel)
- PixelFormatCanonical = 0x00200000, // ?
-
- PixelFormatUndefined = 0,
- PixelFormatDontCare = 0,
-
- PixelFormat1bppIndexed = 1 | ( 1 << 8) | PixelFormatIndexed
- | PixelFormatGDI,
- PixelFormat4bppIndexed = 2 | ( 4 << 8) | PixelFormatIndexed
- | PixelFormatGDI,
- PixelFormat8bppIndexed = 3 | ( 8 << 8) | PixelFormatIndexed
- | PixelFormatGDI,
- PixelFormat16bppGrayScale = 4 | (16 << 8) | PixelFormatExtended,
- PixelFormat16bppRGB555 = 5 | (16 << 8) | PixelFormatGDI,
- PixelFormat16bppRGB565 = 6 | (16 << 8) | PixelFormatGDI,
- PixelFormat16bppARGB1555 = 7 | (16 << 8) | PixelFormatAlpha
- | PixelFormatGDI,
- PixelFormat24bppRGB = 8 | (24 << 8) | PixelFormatGDI,
- PixelFormat32bppRGB = 9 | (32 << 8) | PixelFormatGDI,
- PixelFormat32bppARGB = 10 | (32 << 8) | PixelFormatAlpha
- | PixelFormatGDI
- | PixelFormatCanonical,
- PixelFormat32bppPARGB = 11 | (32 << 8) | PixelFormatAlpha
- | PixelFormatPAlpha
- | PixelFormatGDI,
- PixelFormat48bppRGB = 12 | (48 << 8) | PixelFormatExtended,
- PixelFormat64bppARGB = 13 | (64 << 8) | PixelFormatAlpha
- | PixelFormatCanonical
- | PixelFormatExtended,
- PixelFormat64bppPARGB = 14 | (64 << 8) | PixelFormatAlpha
- | PixelFormatPAlpha
- | PixelFormatExtended,
- PixelFormat24bppBGR = 15 | (24 << 8) | PixelFormatGDI,
- PixelFormatMax = 16
-};
-
-#else
-
-typedef INT PixelFormat;
-
-#define PixelFormatIndexed 0x00010000 // Indexes into a palette
-#define PixelFormatGDI 0x00020000 // Is a GDI-supported format
-#define PixelFormatAlpha 0x00040000 // Has an alpha component
-#define PixelFormatPAlpha 0x00080000 // Uses pre-multiplied alpha
-#define PixelFormatExtended 0x00100000 // Uses extended color (16 bits per channel)
-#define PixelFormatCanonical 0x00200000 // ?
-
-#define PixelFormatUndefined 0
-#define PixelFormatDontCare 0
-
-#define PixelFormat1bppIndexed (1 | ( 1 << 8) | PixelFormatIndexed | PixelFormatGDI)
-#define PixelFormat4bppIndexed (2 | ( 4 << 8) | PixelFormatIndexed | PixelFormatGDI)
-#define PixelFormat8bppIndexed (3 | ( 8 << 8) | PixelFormatIndexed | PixelFormatGDI)
-#define PixelFormat16bppGrayScale (4 | (16 << 8) | PixelFormatExtended)
-#define PixelFormat16bppRGB555 (5 | (16 << 8) | PixelFormatGDI)
-#define PixelFormat16bppRGB565 (6 | (16 << 8) | PixelFormatGDI)
-#define PixelFormat16bppARGB1555 (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI)
-#define PixelFormat24bppRGB (8 | (24 << 8) | PixelFormatGDI)
-#define PixelFormat32bppRGB (9 | (32 << 8) | PixelFormatGDI)
-#define PixelFormat32bppARGB (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical)
-#define PixelFormat32bppPARGB (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI)
-#define PixelFormat48bppRGB (12 | (48 << 8) | PixelFormatExtended)
-#define PixelFormat64bppARGB (13 | (64 << 8) | PixelFormatAlpha | PixelFormatCanonical | PixelFormatExtended)
-#define PixelFormat64bppPARGB (14 | (64 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatExtended)
-#define PixelFormatMax 15
-
-#endif
-
-
-/*
- * Return the pixel size for the specified format (in bits)
- */
-
-inline UINT
-GetPixelFormatSize(
- PixelFormat pixfmt
- )
-{
- return (pixfmt >> 8) & 0xff;
-}
-
-/*
- * Determine if the specified pixel format is an indexed color format
- */
-
-inline BOOL
-IsIndexedPixelFormat(
- PixelFormat pixfmt
- )
-{
- return (pixfmt & PixelFormatIndexed) != 0;
-}
-
-/*
- * Determine if the pixel format can have alpha channel
- */
-
-inline BOOL
-IsAlphaPixelFormat(
- PixelFormat pixfmt
-)
-{
- return (pixfmt & PixelFormatAlpha) != 0;
-}
-
-/*
- * Determine if the pixel format is an extended format,
- * i.e. supports 16-bit per channel
- */
-
-inline BOOL
-IsExtendedPixelFormat(
- PixelFormat pixfmt
- )
-{
- return (pixfmt & PixelFormatExtended) != 0;
-}
-
-/*
- * Determine if the pixel format is canonical format:
- * PixelFormat32bppARGB
- * PixelFormat32bppPARGB
- * PixelFormat64bppARGB
- * PixelFormat64bppPARGB
- */
-
-inline BOOL
-IsCanonicalPixelFormat(
- PixelFormat pixfmt
- )
-{
- return (pixfmt & PixelFormatCanonical) != 0;
-}
-
-/*
- * Color palette
- * palette entries are limited to 32bpp ARGB pixel format
- */
-
-enum PaletteFlags
-{
- PaletteFlagsHasAlpha = 0x0001,
- PaletteFlagsGrayScale = 0x0002,
- PaletteFlagsHalftone = 0x0004
-};
-
-struct ColorPalette
-{
-public:
- UINT Flags; // palette flags
- UINT Count; // number of color entries
- ARGB Entries[1]; // palette color entries
-};
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* Gdiplus pixel formats
+*
+* Abstract:
+*
+* Definitions for color types, palettes, pixel format IDs.
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSPIXELFORMATS_H
+#define _GDIPLUSPIXELFORMATS_H
+
+/*
+ * 32-bit and 64-bit ARGB pixel value
+ */
+
+typedef DWORD ARGB;
+typedef DWORDLONG ARGB64;
+
+#define ALPHA_SHIFT 24
+#define RED_SHIFT 16
+#define GREEN_SHIFT 8
+#define BLUE_SHIFT 0
+#define ALPHA_MASK ((ARGB) 0xff << ALPHA_SHIFT)
+
+/*
+ * In-memory pixel data formats:
+ * bits 0-7 = format index
+ * bits 8-15 = pixel size (in bits)
+ * bits 16-23 = flags
+ * bits 24-31 = reserved
+ */
+
+#ifndef DCR_USE_NEW_105760
+
+enum PixelFormat
+{
+ PixelFormatIndexed = 0x00010000, // Indexes into a palette
+ PixelFormatGDI = 0x00020000, // Is a GDI-supported format
+ PixelFormatAlpha = 0x00040000, // Has an alpha component
+ PixelFormatPAlpha = 0x00080000, // Uses pre-multiplied alpha
+ PixelFormatExtended = 0x00100000, // Uses extended color (16 bits per channel)
+ PixelFormatCanonical = 0x00200000, // ?
+
+ PixelFormatUndefined = 0,
+ PixelFormatDontCare = 0,
+
+ PixelFormat1bppIndexed = 1 | ( 1 << 8) | PixelFormatIndexed
+ | PixelFormatGDI,
+ PixelFormat4bppIndexed = 2 | ( 4 << 8) | PixelFormatIndexed
+ | PixelFormatGDI,
+ PixelFormat8bppIndexed = 3 | ( 8 << 8) | PixelFormatIndexed
+ | PixelFormatGDI,
+ PixelFormat16bppGrayScale = 4 | (16 << 8) | PixelFormatExtended,
+ PixelFormat16bppRGB555 = 5 | (16 << 8) | PixelFormatGDI,
+ PixelFormat16bppRGB565 = 6 | (16 << 8) | PixelFormatGDI,
+ PixelFormat16bppARGB1555 = 7 | (16 << 8) | PixelFormatAlpha
+ | PixelFormatGDI,
+ PixelFormat24bppRGB = 8 | (24 << 8) | PixelFormatGDI,
+ PixelFormat32bppRGB = 9 | (32 << 8) | PixelFormatGDI,
+ PixelFormat32bppARGB = 10 | (32 << 8) | PixelFormatAlpha
+ | PixelFormatGDI
+ | PixelFormatCanonical,
+ PixelFormat32bppPARGB = 11 | (32 << 8) | PixelFormatAlpha
+ | PixelFormatPAlpha
+ | PixelFormatGDI,
+ PixelFormat48bppRGB = 12 | (48 << 8) | PixelFormatExtended,
+ PixelFormat64bppARGB = 13 | (64 << 8) | PixelFormatAlpha
+ | PixelFormatCanonical
+ | PixelFormatExtended,
+ PixelFormat64bppPARGB = 14 | (64 << 8) | PixelFormatAlpha
+ | PixelFormatPAlpha
+ | PixelFormatExtended,
+ PixelFormat24bppBGR = 15 | (24 << 8) | PixelFormatGDI,
+ PixelFormatMax = 16
+};
+
+#else
+
+typedef INT PixelFormat;
+
+#define PixelFormatIndexed 0x00010000 // Indexes into a palette
+#define PixelFormatGDI 0x00020000 // Is a GDI-supported format
+#define PixelFormatAlpha 0x00040000 // Has an alpha component
+#define PixelFormatPAlpha 0x00080000 // Uses pre-multiplied alpha
+#define PixelFormatExtended 0x00100000 // Uses extended color (16 bits per channel)
+#define PixelFormatCanonical 0x00200000 // ?
+
+#define PixelFormatUndefined 0
+#define PixelFormatDontCare 0
+
+#define PixelFormat1bppIndexed (1 | ( 1 << 8) | PixelFormatIndexed | PixelFormatGDI)
+#define PixelFormat4bppIndexed (2 | ( 4 << 8) | PixelFormatIndexed | PixelFormatGDI)
+#define PixelFormat8bppIndexed (3 | ( 8 << 8) | PixelFormatIndexed | PixelFormatGDI)
+#define PixelFormat16bppGrayScale (4 | (16 << 8) | PixelFormatExtended)
+#define PixelFormat16bppRGB555 (5 | (16 << 8) | PixelFormatGDI)
+#define PixelFormat16bppRGB565 (6 | (16 << 8) | PixelFormatGDI)
+#define PixelFormat16bppARGB1555 (7 | (16 << 8) | PixelFormatAlpha | PixelFormatGDI)
+#define PixelFormat24bppRGB (8 | (24 << 8) | PixelFormatGDI)
+#define PixelFormat32bppRGB (9 | (32 << 8) | PixelFormatGDI)
+#define PixelFormat32bppARGB (10 | (32 << 8) | PixelFormatAlpha | PixelFormatGDI | PixelFormatCanonical)
+#define PixelFormat32bppPARGB (11 | (32 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatGDI)
+#define PixelFormat48bppRGB (12 | (48 << 8) | PixelFormatExtended)
+#define PixelFormat64bppARGB (13 | (64 << 8) | PixelFormatAlpha | PixelFormatCanonical | PixelFormatExtended)
+#define PixelFormat64bppPARGB (14 | (64 << 8) | PixelFormatAlpha | PixelFormatPAlpha | PixelFormatExtended)
+#define PixelFormatMax 15
+
+#endif
+
+
+/*
+ * Return the pixel size for the specified format (in bits)
+ */
+
+inline UINT
+GetPixelFormatSize(
+ PixelFormat pixfmt
+ )
+{
+ return (pixfmt >> 8) & 0xff;
+}
+
+/*
+ * Determine if the specified pixel format is an indexed color format
+ */
+
+inline BOOL
+IsIndexedPixelFormat(
+ PixelFormat pixfmt
+ )
+{
+ return (pixfmt & PixelFormatIndexed) != 0;
+}
+
+/*
+ * Determine if the pixel format can have alpha channel
+ */
+
+inline BOOL
+IsAlphaPixelFormat(
+ PixelFormat pixfmt
+)
+{
+ return (pixfmt & PixelFormatAlpha) != 0;
+}
+
+/*
+ * Determine if the pixel format is an extended format,
+ * i.e. supports 16-bit per channel
+ */
+
+inline BOOL
+IsExtendedPixelFormat(
+ PixelFormat pixfmt
+ )
+{
+ return (pixfmt & PixelFormatExtended) != 0;
+}
+
+/*
+ * Determine if the pixel format is canonical format:
+ * PixelFormat32bppARGB
+ * PixelFormat32bppPARGB
+ * PixelFormat64bppARGB
+ * PixelFormat64bppPARGB
+ */
+
+inline BOOL
+IsCanonicalPixelFormat(
+ PixelFormat pixfmt
+ )
+{
+ return (pixfmt & PixelFormatCanonical) != 0;
+}
+
+/*
+ * Color palette
+ * palette entries are limited to 32bpp ARGB pixel format
+ */
+
+enum PaletteFlags
+{
+ PaletteFlagsHasAlpha = 0x0001,
+ PaletteFlagsGrayScale = 0x0002,
+ PaletteFlagsHalftone = 0x0004
+};
+
+struct ColorPalette
+{
+public:
+ UINT Flags; // palette flags
+ UINT Count; // number of color entries
+ ARGB Entries[1]; // palette color entries
+};
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusRegion.h b/core/src/fxge/Microsoft SDK/include/GdiPlusRegion.h
index dd1d20e273..cfb40a17dc 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusRegion.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusRegion.h
@@ -1,498 +1,498 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusRegion.h
-*
-* Abstract:
-*
-* Region API related declarations
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSREGION_H
-#define _GDIPLUSREGION_H
-
-/**
- * Construct a new region object
- */
-
-inline
-Region::Region()
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegion(&region);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN const RectF& rect)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionRect(&rect, &region);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN const Rect& rect)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionRectI(&rect, &region);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN const GraphicsPath* path)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionPath(path->nativePath, &region);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN const BYTE* regionData, IN INT size)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionRgnData(regionData, size, &region);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN HRGN hRgn)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionHrgn(hRgn, &region);
-
- SetNativeRegion(region);
-}
-
-inline
-Region* Region::FromHRGN(IN HRGN hRgn)
-{
- GpRegion *region = NULL;
-
- if (DllExports::GdipCreateRegionHrgn(hRgn, &region) == Ok)
- {
- Region* newRegion = new Region(region);
-
- if (newRegion == NULL)
- {
- DllExports::GdipDeleteRegion(region);
- }
-
- return newRegion;
- }
- else
- return NULL;
-}
-
-inline
-Region::~Region()
-{
- DllExports::GdipDeleteRegion(nativeRegion);
-}
-
-/**
- * Make a copy of the region object
- */
-inline Region*
-Region::Clone() const
-{
- GpRegion *region = NULL;
-
- SetStatus(DllExports::GdipCloneRegion(nativeRegion, &region));
-
- return new Region(region);
-}
-
-inline Status
-Region::MakeInfinite()
-{
- return SetStatus(DllExports::GdipSetInfinite(nativeRegion));
-}
-
-inline Status
-Region::MakeEmpty()
-{
- return SetStatus(DllExports::GdipSetEmpty(nativeRegion));
-}
-
-/**
- * Region operations
- */
-inline Status
-Region::Intersect(IN const RectF& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeIntersect));
-}
-
-inline Status
-Region::Intersect(IN const Rect& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeIntersect));
-}
-
-inline Status
-Region::Intersect(IN const GraphicsPath* path)
-{
- return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion, path->nativePath, CombineModeIntersect));
-}
-
-inline Status
-Region::Intersect(IN const Region* region)
-{
- return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion, region->nativeRegion, CombineModeIntersect));
-}
-
-inline Status
-Region::Union(IN const RectF& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeUnion));
-}
-
-inline Status
-Region::Union(IN const Rect& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeUnion));
-}
-
-inline Status
-Region::Union(IN const GraphicsPath* path)
-{
- return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion, path->nativePath, CombineModeUnion));
-}
-
-inline Status
-Region::Union(IN const Region* region)
-{
- return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion, region->nativeRegion, CombineModeUnion));
-}
-
-inline Status
-Region::Xor(IN const RectF& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeXor));
-}
-
-inline Status
-Region::Xor(IN const Rect& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeXor));
-}
-
-inline Status
-Region::Xor(IN const GraphicsPath* path)
-{
- return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion, path->nativePath, CombineModeXor));
-}
-
-inline Status
-Region::Xor(IN const Region* region)
-{
- return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion, region->nativeRegion, CombineModeXor));
-}
-
-inline Status
-Region::Exclude(IN const RectF& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeExclude));
-}
-
-inline Status
-Region::Exclude(IN const Rect& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeExclude));
-}
-
-inline Status
-Region::Exclude(IN const GraphicsPath* path)
-{
- return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion, path->nativePath, CombineModeExclude));
-}
-
-inline Status
-Region::Exclude(IN const Region* region)
-{
- return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion,
- region->nativeRegion, CombineModeExclude));
-}
-
-inline Status
-Region::Complement(IN const RectF& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeComplement));
-}
-
-inline Status
-Region::Complement(IN const Rect& rect)
-{
- return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeComplement));
-}
-
-inline Status
-Region::Complement(IN const GraphicsPath* path)
-{
- return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion,
- path->nativePath, CombineModeComplement));
-}
-
-inline Status
-Region::Complement(IN const Region* region)
-{
- return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion,
- region->nativeRegion, CombineModeComplement));
-}
-
-/**
- * Transform operations
- */
-inline Status
-Region::Translate(IN REAL dx,
- IN REAL dy)
-{
- return SetStatus(DllExports::GdipTranslateRegion(nativeRegion, dx, dy));
-}
-
-inline Status
-Region::Translate(IN INT dx,
- IN INT dy)
-{
- return SetStatus(DllExports::GdipTranslateRegionI(nativeRegion, dx, dy));
-}
-
-inline Status
-Region::Transform(IN const Matrix* matrix)
-{
- return SetStatus(DllExports::GdipTransformRegion(nativeRegion, matrix->nativeMatrix));
-}
-
-/**
- * Get region attributes
- */
-inline Status
-Region::GetBounds(OUT RectF* rect,
- IN const Graphics* g) const
-{
- return SetStatus(DllExports::GdipGetRegionBounds(nativeRegion,
- g->nativeGraphics,
- rect));
-}
-
-inline Status
-Region::GetBounds(OUT Rect* rect,
- IN const Graphics* g) const
-{
- return SetStatus(DllExports::GdipGetRegionBoundsI(nativeRegion,
- g->nativeGraphics,
- rect));
-}
-
-inline HRGN
-Region::GetHRGN(IN const Graphics* g) const
-{
- HRGN hrgn;
-
- SetStatus(DllExports::GdipGetRegionHRgn(nativeRegion,
- g->nativeGraphics,
- &hrgn));
-
- return hrgn;
-}
-
-inline BOOL
-Region::IsEmpty(IN const Graphics *g) const
-{
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsEmptyRegion(nativeRegion,
- g->nativeGraphics,
- &booln));
-
- return booln;
-}
-
-inline BOOL
-Region::IsInfinite(IN const Graphics *g) const
-{
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsInfiniteRegion(nativeRegion,
- g->nativeGraphics,
- &booln));
-
- return booln;
-}
-
-inline BOOL
-Region::Equals(IN const Region* region,
- IN const Graphics* g) const
-{
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsEqualRegion(nativeRegion,
- region->nativeRegion,
- g->nativeGraphics,
- &booln));
- return booln;
-}
-
-// Get the size of the buffer needed for the GetData method
-inline UINT
-Region::GetDataSize() const
-{
- UINT bufferSize = 0;
-
- SetStatus(DllExports::GdipGetRegionDataSize(nativeRegion, &bufferSize));
-
- return bufferSize;
-}
-
-// buffer - where to put the data
-// bufferSize - how big the buffer is (should be at least as big as GetDataSize())
-// sizeFilled - if not NULL, this is an OUT param that says how many bytes
-// of data were written to the buffer.
-inline Status
-Region::GetData(OUT BYTE* buffer,
- IN UINT bufferSize,
- OUT UINT* sizeFilled) const
-{
- return SetStatus(DllExports::GdipGetRegionData(nativeRegion, buffer, bufferSize, sizeFilled));
-}
-
-/**
- * Hit testing operations
- */
-inline BOOL
-Region::IsVisible(IN const PointF& point,
- IN const Graphics* g) const
-{
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsVisibleRegionPoint(nativeRegion,
- point.X, point.Y,
- (g == NULL) ? NULL : g->nativeGraphics,
- &booln));
- return booln;
-}
-
-inline BOOL
-Region::IsVisible(IN const RectF& rect,
- IN const Graphics* g) const
-{
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsVisibleRegionRect(nativeRegion, rect.X,
- rect.Y, rect.Width,
- rect.Height,
- (g == NULL) ? NULL : g->nativeGraphics,
- &booln));
- return booln;
-}
-
-inline BOOL
-Region::IsVisible(IN const Point& point,
- IN const Graphics* g) const
-{
- BOOL booln = FALSE;
-
-
- SetStatus(DllExports::GdipIsVisibleRegionPointI(nativeRegion,
- point.X,
- point.Y,
- (g == NULL) ? NULL : g->nativeGraphics,
- &booln));
- return booln;
-}
-
-inline BOOL
-Region::IsVisible(IN const Rect& rect,
- IN const Graphics* g) const
-{
- BOOL booln = FALSE;
-
- SetStatus(DllExports::GdipIsVisibleRegionRectI(nativeRegion,
- rect.X,
- rect.Y,
- rect.Width,
- rect.Height,
- (g == NULL) ? NULL : g->nativeGraphics,
- &booln));
- return booln;
-}
-
-inline UINT
-Region::GetRegionScansCount(IN const Matrix* matrix) const
-{
- UINT count = 0;
-
- SetStatus(DllExports::GdipGetRegionScansCount(nativeRegion,
- &count,
- matrix->nativeMatrix));
- return count;
-}
-
-inline Status
-Region::GetRegionScans(
- IN const Matrix* matrix,
- OUT RectF* rects,
- IN OUT INT* count) const
-{
- return SetStatus(DllExports::GdipGetRegionScans(nativeRegion,
- rects,
- count,
- matrix->nativeMatrix));
-}
-
-// If rects is NULL, return the count of rects in the region.
-// Otherwise, assume rects is big enough to hold all the region rects
-// and fill them in and return the number of rects filled in.
-// The rects are returned in the units specified by the matrix
-// (which is typically a world-to-device transform).
-// Note that the number of rects returned can vary, depending on the
-// matrix that is used.
-inline Status
-Region::GetRegionScans(
- IN const Matrix* matrix,
- OUT Rect* rects, // NULL to just get the count
- IN OUT INT* count) const
-{
- return SetStatus(DllExports::GdipGetRegionScansI(nativeRegion,
- rects,
- count,
- matrix->nativeMatrix));
-}
-
-// protected method
-inline Region::Region(GpRegion* nativeRegion)
-{
- SetNativeRegion(nativeRegion);
-}
-
-// protected method
-inline VOID Region::SetNativeRegion(GpRegion* nativeRegion)
-{
- this->nativeRegion = nativeRegion;
-}
-
-inline Status Region::GetLastStatus() const
-{
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
-}
-
-#endif // !_GDIPLUSREGION_H
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusRegion.h
+*
+* Abstract:
+*
+* Region API related declarations
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSREGION_H
+#define _GDIPLUSREGION_H
+
+/**
+ * Construct a new region object
+ */
+
+inline
+Region::Region()
+{
+ GpRegion *region = NULL;
+
+ lastResult = DllExports::GdipCreateRegion(&region);
+
+ SetNativeRegion(region);
+}
+
+inline
+Region::Region(IN const RectF& rect)
+{
+ GpRegion *region = NULL;
+
+ lastResult = DllExports::GdipCreateRegionRect(&rect, &region);
+
+ SetNativeRegion(region);
+}
+
+inline
+Region::Region(IN const Rect& rect)
+{
+ GpRegion *region = NULL;
+
+ lastResult = DllExports::GdipCreateRegionRectI(&rect, &region);
+
+ SetNativeRegion(region);
+}
+
+inline
+Region::Region(IN const GraphicsPath* path)
+{
+ GpRegion *region = NULL;
+
+ lastResult = DllExports::GdipCreateRegionPath(path->nativePath, &region);
+
+ SetNativeRegion(region);
+}
+
+inline
+Region::Region(IN const BYTE* regionData, IN INT size)
+{
+ GpRegion *region = NULL;
+
+ lastResult = DllExports::GdipCreateRegionRgnData(regionData, size, &region);
+
+ SetNativeRegion(region);
+}
+
+inline
+Region::Region(IN HRGN hRgn)
+{
+ GpRegion *region = NULL;
+
+ lastResult = DllExports::GdipCreateRegionHrgn(hRgn, &region);
+
+ SetNativeRegion(region);
+}
+
+inline
+Region* Region::FromHRGN(IN HRGN hRgn)
+{
+ GpRegion *region = NULL;
+
+ if (DllExports::GdipCreateRegionHrgn(hRgn, &region) == Ok)
+ {
+ Region* newRegion = new Region(region);
+
+ if (newRegion == NULL)
+ {
+ DllExports::GdipDeleteRegion(region);
+ }
+
+ return newRegion;
+ }
+ else
+ return NULL;
+}
+
+inline
+Region::~Region()
+{
+ DllExports::GdipDeleteRegion(nativeRegion);
+}
+
+/**
+ * Make a copy of the region object
+ */
+inline Region*
+Region::Clone() const
+{
+ GpRegion *region = NULL;
+
+ SetStatus(DllExports::GdipCloneRegion(nativeRegion, &region));
+
+ return new Region(region);
+}
+
+inline Status
+Region::MakeInfinite()
+{
+ return SetStatus(DllExports::GdipSetInfinite(nativeRegion));
+}
+
+inline Status
+Region::MakeEmpty()
+{
+ return SetStatus(DllExports::GdipSetEmpty(nativeRegion));
+}
+
+/**
+ * Region operations
+ */
+inline Status
+Region::Intersect(IN const RectF& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeIntersect));
+}
+
+inline Status
+Region::Intersect(IN const Rect& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeIntersect));
+}
+
+inline Status
+Region::Intersect(IN const GraphicsPath* path)
+{
+ return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion, path->nativePath, CombineModeIntersect));
+}
+
+inline Status
+Region::Intersect(IN const Region* region)
+{
+ return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion, region->nativeRegion, CombineModeIntersect));
+}
+
+inline Status
+Region::Union(IN const RectF& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeUnion));
+}
+
+inline Status
+Region::Union(IN const Rect& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeUnion));
+}
+
+inline Status
+Region::Union(IN const GraphicsPath* path)
+{
+ return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion, path->nativePath, CombineModeUnion));
+}
+
+inline Status
+Region::Union(IN const Region* region)
+{
+ return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion, region->nativeRegion, CombineModeUnion));
+}
+
+inline Status
+Region::Xor(IN const RectF& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeXor));
+}
+
+inline Status
+Region::Xor(IN const Rect& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeXor));
+}
+
+inline Status
+Region::Xor(IN const GraphicsPath* path)
+{
+ return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion, path->nativePath, CombineModeXor));
+}
+
+inline Status
+Region::Xor(IN const Region* region)
+{
+ return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion, region->nativeRegion, CombineModeXor));
+}
+
+inline Status
+Region::Exclude(IN const RectF& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeExclude));
+}
+
+inline Status
+Region::Exclude(IN const Rect& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeExclude));
+}
+
+inline Status
+Region::Exclude(IN const GraphicsPath* path)
+{
+ return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion, path->nativePath, CombineModeExclude));
+}
+
+inline Status
+Region::Exclude(IN const Region* region)
+{
+ return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion,
+ region->nativeRegion, CombineModeExclude));
+}
+
+inline Status
+Region::Complement(IN const RectF& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRect(nativeRegion, &rect, CombineModeComplement));
+}
+
+inline Status
+Region::Complement(IN const Rect& rect)
+{
+ return SetStatus(DllExports::GdipCombineRegionRectI(nativeRegion, &rect, CombineModeComplement));
+}
+
+inline Status
+Region::Complement(IN const GraphicsPath* path)
+{
+ return SetStatus(DllExports::GdipCombineRegionPath(nativeRegion,
+ path->nativePath, CombineModeComplement));
+}
+
+inline Status
+Region::Complement(IN const Region* region)
+{
+ return SetStatus(DllExports::GdipCombineRegionRegion(nativeRegion,
+ region->nativeRegion, CombineModeComplement));
+}
+
+/**
+ * Transform operations
+ */
+inline Status
+Region::Translate(IN REAL dx,
+ IN REAL dy)
+{
+ return SetStatus(DllExports::GdipTranslateRegion(nativeRegion, dx, dy));
+}
+
+inline Status
+Region::Translate(IN INT dx,
+ IN INT dy)
+{
+ return SetStatus(DllExports::GdipTranslateRegionI(nativeRegion, dx, dy));
+}
+
+inline Status
+Region::Transform(IN const Matrix* matrix)
+{
+ return SetStatus(DllExports::GdipTransformRegion(nativeRegion, matrix->nativeMatrix));
+}
+
+/**
+ * Get region attributes
+ */
+inline Status
+Region::GetBounds(OUT RectF* rect,
+ IN const Graphics* g) const
+{
+ return SetStatus(DllExports::GdipGetRegionBounds(nativeRegion,
+ g->nativeGraphics,
+ rect));
+}
+
+inline Status
+Region::GetBounds(OUT Rect* rect,
+ IN const Graphics* g) const
+{
+ return SetStatus(DllExports::GdipGetRegionBoundsI(nativeRegion,
+ g->nativeGraphics,
+ rect));
+}
+
+inline HRGN
+Region::GetHRGN(IN const Graphics* g) const
+{
+ HRGN hrgn;
+
+ SetStatus(DllExports::GdipGetRegionHRgn(nativeRegion,
+ g->nativeGraphics,
+ &hrgn));
+
+ return hrgn;
+}
+
+inline BOOL
+Region::IsEmpty(IN const Graphics *g) const
+{
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsEmptyRegion(nativeRegion,
+ g->nativeGraphics,
+ &booln));
+
+ return booln;
+}
+
+inline BOOL
+Region::IsInfinite(IN const Graphics *g) const
+{
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsInfiniteRegion(nativeRegion,
+ g->nativeGraphics,
+ &booln));
+
+ return booln;
+}
+
+inline BOOL
+Region::Equals(IN const Region* region,
+ IN const Graphics* g) const
+{
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsEqualRegion(nativeRegion,
+ region->nativeRegion,
+ g->nativeGraphics,
+ &booln));
+ return booln;
+}
+
+// Get the size of the buffer needed for the GetData method
+inline UINT
+Region::GetDataSize() const
+{
+ UINT bufferSize = 0;
+
+ SetStatus(DllExports::GdipGetRegionDataSize(nativeRegion, &bufferSize));
+
+ return bufferSize;
+}
+
+// buffer - where to put the data
+// bufferSize - how big the buffer is (should be at least as big as GetDataSize())
+// sizeFilled - if not NULL, this is an OUT param that says how many bytes
+// of data were written to the buffer.
+inline Status
+Region::GetData(OUT BYTE* buffer,
+ IN UINT bufferSize,
+ OUT UINT* sizeFilled) const
+{
+ return SetStatus(DllExports::GdipGetRegionData(nativeRegion, buffer, bufferSize, sizeFilled));
+}
+
+/**
+ * Hit testing operations
+ */
+inline BOOL
+Region::IsVisible(IN const PointF& point,
+ IN const Graphics* g) const
+{
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsVisibleRegionPoint(nativeRegion,
+ point.X, point.Y,
+ (g == NULL) ? NULL : g->nativeGraphics,
+ &booln));
+ return booln;
+}
+
+inline BOOL
+Region::IsVisible(IN const RectF& rect,
+ IN const Graphics* g) const
+{
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsVisibleRegionRect(nativeRegion, rect.X,
+ rect.Y, rect.Width,
+ rect.Height,
+ (g == NULL) ? NULL : g->nativeGraphics,
+ &booln));
+ return booln;
+}
+
+inline BOOL
+Region::IsVisible(IN const Point& point,
+ IN const Graphics* g) const
+{
+ BOOL booln = FALSE;
+
+
+ SetStatus(DllExports::GdipIsVisibleRegionPointI(nativeRegion,
+ point.X,
+ point.Y,
+ (g == NULL) ? NULL : g->nativeGraphics,
+ &booln));
+ return booln;
+}
+
+inline BOOL
+Region::IsVisible(IN const Rect& rect,
+ IN const Graphics* g) const
+{
+ BOOL booln = FALSE;
+
+ SetStatus(DllExports::GdipIsVisibleRegionRectI(nativeRegion,
+ rect.X,
+ rect.Y,
+ rect.Width,
+ rect.Height,
+ (g == NULL) ? NULL : g->nativeGraphics,
+ &booln));
+ return booln;
+}
+
+inline UINT
+Region::GetRegionScansCount(IN const Matrix* matrix) const
+{
+ UINT count = 0;
+
+ SetStatus(DllExports::GdipGetRegionScansCount(nativeRegion,
+ &count,
+ matrix->nativeMatrix));
+ return count;
+}
+
+inline Status
+Region::GetRegionScans(
+ IN const Matrix* matrix,
+ OUT RectF* rects,
+ IN OUT INT* count) const
+{
+ return SetStatus(DllExports::GdipGetRegionScans(nativeRegion,
+ rects,
+ count,
+ matrix->nativeMatrix));
+}
+
+// If rects is NULL, return the count of rects in the region.
+// Otherwise, assume rects is big enough to hold all the region rects
+// and fill them in and return the number of rects filled in.
+// The rects are returned in the units specified by the matrix
+// (which is typically a world-to-device transform).
+// Note that the number of rects returned can vary, depending on the
+// matrix that is used.
+inline Status
+Region::GetRegionScans(
+ IN const Matrix* matrix,
+ OUT Rect* rects, // NULL to just get the count
+ IN OUT INT* count) const
+{
+ return SetStatus(DllExports::GdipGetRegionScansI(nativeRegion,
+ rects,
+ count,
+ matrix->nativeMatrix));
+}
+
+// protected method
+inline Region::Region(GpRegion* nativeRegion)
+{
+ SetNativeRegion(nativeRegion);
+}
+
+// protected method
+inline VOID Region::SetNativeRegion(GpRegion* nativeRegion)
+{
+ this->nativeRegion = nativeRegion;
+}
+
+inline Status Region::GetLastStatus() const
+{
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+}
+
+#endif // !_GDIPLUSREGION_H
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusStringFormat.h b/core/src/fxge/Microsoft SDK/include/GdiPlusStringFormat.h
index 1c9ddb50ec..b4ed431a06 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusStringFormat.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusStringFormat.h
@@ -1,381 +1,381 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusStringFormat.h
-*
-* Abstract:
-*
-* String format specification for DrawString and text APIs
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSSTRINGFORMAT_H
-#define _GDIPLUSSTRINGFORMAT_H
-
-
-class StringFormat : public GdiplusBase
-{
-public:
- friend class Graphics;
- friend class GraphicsPath;
-
-
- StringFormat(
- IN INT formatFlags = 0,
- IN LANGID language = LANG_NEUTRAL
- )
- {
- nativeFormat = NULL;
- lastError = DllExports::GdipCreateStringFormat(
- formatFlags,
- language,
- &nativeFormat
- );
- }
-
- static const StringFormat *GenericDefault();
- static const StringFormat *GenericTypographic();
-
- // Constructor based on existing string format
-
- StringFormat(
- IN const StringFormat *format
- )
- {
- nativeFormat = NULL;
- lastError = DllExports::GdipCloneStringFormat(
- format ? format->nativeFormat : NULL,
- &nativeFormat
- );
- }
-
- StringFormat *Clone() const
- {
- GpStringFormat *clonedStringFormat = NULL;
-
- lastError = DllExports::GdipCloneStringFormat(
- nativeFormat,
- &clonedStringFormat
- );
-
- if (lastError == Ok)
- return new StringFormat(clonedStringFormat, lastError);
- else
- return NULL;
- }
-
- ~StringFormat()
- {
- DllExports::GdipDeleteStringFormat(nativeFormat);
- }
-
- Status SetFormatFlags(IN INT flags)
- {
- return SetStatus(DllExports::GdipSetStringFormatFlags(
- nativeFormat,
- flags
- ));
- }
-
- INT GetFormatFlags() const
- {
- INT flags;
- SetStatus(DllExports::GdipGetStringFormatFlags(nativeFormat, &flags));
- return flags;
- }
-
-#ifndef DCR_USE_NEW_152154
- Status SetLineSpacing(
- IN REAL amount = 1.0f,
- IN LineSpacing method = LineSpacingRecommended
- )
- {
- return SetStatus(DllExports::GdipSetStringFormatLineSpacing(
- nativeFormat,
- amount,
- method
- ));
- }
-#endif
-
- Status SetAlignment(IN StringAlignment align)
- {
- return SetStatus(DllExports::GdipSetStringFormatAlign(
- nativeFormat,
- align
- ));
- }
-
- StringAlignment GetAlignment() const
- {
- StringAlignment alignment;
- SetStatus(DllExports::GdipGetStringFormatAlign(
- nativeFormat,
- &alignment
- ));
- return alignment;
- }
-
- Status SetLineAlignment(IN StringAlignment align)
- {
- return SetStatus(DllExports::GdipSetStringFormatLineAlign(
- nativeFormat,
- align
- ));
- }
-
- StringAlignment GetLineAlignment() const
- {
- StringAlignment alignment;
- SetStatus(DllExports::GdipGetStringFormatLineAlign(
- nativeFormat,
- &alignment
- ));
- return alignment;
- }
-
- Status SetHotkeyPrefix(IN HotkeyPrefix hotkeyPrefix)
- {
- return SetStatus(DllExports::GdipSetStringFormatHotkeyPrefix(
- nativeFormat,
- (INT)hotkeyPrefix
- ));
- }
-
- HotkeyPrefix GetHotkeyPrefix() const
- {
- HotkeyPrefix hotkeyPrefix;
- SetStatus(DllExports::GdipGetStringFormatHotkeyPrefix(
- nativeFormat,
- (INT*)&hotkeyPrefix
- ));
- return hotkeyPrefix;
- }
-
- Status SetTabStops(
- IN REAL firstTabOffset,
- IN INT count,
- IN const REAL *tabStops
- )
- {
- return SetStatus(DllExports::GdipSetStringFormatTabStops(
- nativeFormat,
- firstTabOffset,
- count,
- tabStops
- ));
- }
-
- INT GetTabStopCount() const
- {
- INT count;
- SetStatus(DllExports::GdipGetStringFormatTabStopCount(nativeFormat, &count));
- return count;
- }
-
- Status GetTabStops(
- IN INT count,
- OUT REAL *firstTabOffset,
- OUT REAL *tabStops
- ) const
- {
- return SetStatus(DllExports::GdipGetStringFormatTabStops(
- nativeFormat,
- count,
- firstTabOffset,
- tabStops
- ));
- }
-
-#ifdef DCR_USE_NEW_146933
- Status SetDigitSubstitution(
- IN LANGID language,
- IN StringDigitSubstitute substitute
- )
- {
- return SetStatus(DllExports::GdipSetStringFormatDigitSubstitution(
- nativeFormat,
- language,
- substitute
- ));
- }
-
- LANGID GetDigitSubstitutionLanguage(
- ) const
- {
- LANGID language;
- SetStatus(DllExports::GdipGetStringFormatDigitSubstitution(
- nativeFormat,
- &language,
- NULL
- ));
- return language;
- }
-
- StringDigitSubstitute GetDigitSubstitutionMethod(
- ) const
- {
- StringDigitSubstitute substitute;
- SetStatus(DllExports::GdipGetStringFormatDigitSubstitution(
- nativeFormat,
- NULL,
- &substitute
- ));
- return substitute;
- }
-#endif // DCR_USE_NEW_146933
-
- // String trimming. How to handle more text than can be displayed
- // in the limits available.
-
- Status SetTrimming(IN StringTrimming trimming)
- {
- return SetStatus(DllExports::GdipSetStringFormatTrimming(
- nativeFormat,
- trimming
- ));
- }
-
- StringTrimming StringFormat::GetTrimming() const
- {
- StringTrimming trimming;
- SetStatus(DllExports::GdipGetStringFormatTrimming(
- nativeFormat,
- &trimming
- ));
- return trimming;
- }
-
-#ifdef DCR_USE_NEW_174340
- Status SetMeasurableCharacterRanges(
- IN INT rangeCount,
- IN const CharacterRange *ranges
- )
- {
- return SetStatus(DllExports::GdipSetStringFormatMeasurableCharacterRanges(
- nativeFormat,
- rangeCount,
- ranges
- ));
- }
-
- INT GetMeasurableCharacterRangeCount()
- {
- INT count;
- SetStatus(DllExports::GdipGetStringFormatMeasurableCharacterRangeCount(
- nativeFormat,
- &count
- ));
- return count;
- }
-#endif
-
- // GetLastStatus - return last error code and clear error code
-
- Status GetLastStatus() const
- {
- Status lastStatus = lastError;
- lastError = Ok;
-
- return lastStatus;
- }
-
-protected:
-
- Status SetStatus(GpStatus newStatus) const
- {
- if (newStatus == Ok)
- {
- return Ok;
- }
- else
- {
- return lastError = newStatus;
- }
- }
-
-
-// Not allowed and move to private
- StringFormat(const StringFormat &source)
- {
- nativeFormat = NULL;
- lastError = DllExports::GdipCloneStringFormat(
- source.nativeFormat,
- &nativeFormat
- );
- }
-
- StringFormat& operator=(const StringFormat &source)
- {
- DllExports::GdipDeleteStringFormat(nativeFormat);
- lastError = DllExports::GdipCloneStringFormat(
- source.nativeFormat,
- &nativeFormat
- );
- return *this;
- }
-
-
- // private constructor for copy
- StringFormat(GpStringFormat * clonedStringFormat, Status status)
- {
- lastError = status;
- nativeFormat = clonedStringFormat;
-
- }
-
- GpStringFormat *nativeFormat;
- mutable Status lastError;
-};
-
-// Generic constant string formats.
-
-static BYTE GenericTypographicStringFormatBuffer[sizeof(StringFormat)] = {0};
-static BYTE GenericDefaultStringFormatBuffer[sizeof(StringFormat)] = {0};
-
-static StringFormat *GenericTypographicStringFormat = NULL;
-static StringFormat *GenericDefaultStringFormat = NULL;
-
-// Define the generic string formats
-
-
-inline const StringFormat *StringFormat::GenericDefault()
-{
- if (GenericDefaultStringFormat != NULL)
- {
- return GenericDefaultStringFormat;
- }
-
- GenericDefaultStringFormat =
- (StringFormat*)GenericDefaultStringFormatBuffer;
-
- GenericDefaultStringFormat->lastError =
- DllExports::GdipStringFormatGetGenericDefault(
- &(GenericDefaultStringFormat->nativeFormat)
- );
-
- return GenericDefaultStringFormat;
-}
-
-inline const StringFormat *StringFormat::GenericTypographic()
-{
- if (GenericTypographicStringFormat != NULL)
- {
- return GenericTypographicStringFormat;
- }
-
- GenericTypographicStringFormat =
- (StringFormat*)GenericTypographicStringFormatBuffer;
-
- GenericTypographicStringFormat->lastError =
- DllExports::GdipStringFormatGetGenericTypographic(
- &GenericTypographicStringFormat->nativeFormat
- );
-
- return GenericTypographicStringFormat;
-}
-
-#endif // !_GDIPLUSSTRINGFORMAT_H
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusStringFormat.h
+*
+* Abstract:
+*
+* String format specification for DrawString and text APIs
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSSTRINGFORMAT_H
+#define _GDIPLUSSTRINGFORMAT_H
+
+
+class StringFormat : public GdiplusBase
+{
+public:
+ friend class Graphics;
+ friend class GraphicsPath;
+
+
+ StringFormat(
+ IN INT formatFlags = 0,
+ IN LANGID language = LANG_NEUTRAL
+ )
+ {
+ nativeFormat = NULL;
+ lastError = DllExports::GdipCreateStringFormat(
+ formatFlags,
+ language,
+ &nativeFormat
+ );
+ }
+
+ static const StringFormat *GenericDefault();
+ static const StringFormat *GenericTypographic();
+
+ // Constructor based on existing string format
+
+ StringFormat(
+ IN const StringFormat *format
+ )
+ {
+ nativeFormat = NULL;
+ lastError = DllExports::GdipCloneStringFormat(
+ format ? format->nativeFormat : NULL,
+ &nativeFormat
+ );
+ }
+
+ StringFormat *Clone() const
+ {
+ GpStringFormat *clonedStringFormat = NULL;
+
+ lastError = DllExports::GdipCloneStringFormat(
+ nativeFormat,
+ &clonedStringFormat
+ );
+
+ if (lastError == Ok)
+ return new StringFormat(clonedStringFormat, lastError);
+ else
+ return NULL;
+ }
+
+ ~StringFormat()
+ {
+ DllExports::GdipDeleteStringFormat(nativeFormat);
+ }
+
+ Status SetFormatFlags(IN INT flags)
+ {
+ return SetStatus(DllExports::GdipSetStringFormatFlags(
+ nativeFormat,
+ flags
+ ));
+ }
+
+ INT GetFormatFlags() const
+ {
+ INT flags;
+ SetStatus(DllExports::GdipGetStringFormatFlags(nativeFormat, &flags));
+ return flags;
+ }
+
+#ifndef DCR_USE_NEW_152154
+ Status SetLineSpacing(
+ IN REAL amount = 1.0f,
+ IN LineSpacing method = LineSpacingRecommended
+ )
+ {
+ return SetStatus(DllExports::GdipSetStringFormatLineSpacing(
+ nativeFormat,
+ amount,
+ method
+ ));
+ }
+#endif
+
+ Status SetAlignment(IN StringAlignment align)
+ {
+ return SetStatus(DllExports::GdipSetStringFormatAlign(
+ nativeFormat,
+ align
+ ));
+ }
+
+ StringAlignment GetAlignment() const
+ {
+ StringAlignment alignment;
+ SetStatus(DllExports::GdipGetStringFormatAlign(
+ nativeFormat,
+ &alignment
+ ));
+ return alignment;
+ }
+
+ Status SetLineAlignment(IN StringAlignment align)
+ {
+ return SetStatus(DllExports::GdipSetStringFormatLineAlign(
+ nativeFormat,
+ align
+ ));
+ }
+
+ StringAlignment GetLineAlignment() const
+ {
+ StringAlignment alignment;
+ SetStatus(DllExports::GdipGetStringFormatLineAlign(
+ nativeFormat,
+ &alignment
+ ));
+ return alignment;
+ }
+
+ Status SetHotkeyPrefix(IN HotkeyPrefix hotkeyPrefix)
+ {
+ return SetStatus(DllExports::GdipSetStringFormatHotkeyPrefix(
+ nativeFormat,
+ (INT)hotkeyPrefix
+ ));
+ }
+
+ HotkeyPrefix GetHotkeyPrefix() const
+ {
+ HotkeyPrefix hotkeyPrefix;
+ SetStatus(DllExports::GdipGetStringFormatHotkeyPrefix(
+ nativeFormat,
+ (INT*)&hotkeyPrefix
+ ));
+ return hotkeyPrefix;
+ }
+
+ Status SetTabStops(
+ IN REAL firstTabOffset,
+ IN INT count,
+ IN const REAL *tabStops
+ )
+ {
+ return SetStatus(DllExports::GdipSetStringFormatTabStops(
+ nativeFormat,
+ firstTabOffset,
+ count,
+ tabStops
+ ));
+ }
+
+ INT GetTabStopCount() const
+ {
+ INT count;
+ SetStatus(DllExports::GdipGetStringFormatTabStopCount(nativeFormat, &count));
+ return count;
+ }
+
+ Status GetTabStops(
+ IN INT count,
+ OUT REAL *firstTabOffset,
+ OUT REAL *tabStops
+ ) const
+ {
+ return SetStatus(DllExports::GdipGetStringFormatTabStops(
+ nativeFormat,
+ count,
+ firstTabOffset,
+ tabStops
+ ));
+ }
+
+#ifdef DCR_USE_NEW_146933
+ Status SetDigitSubstitution(
+ IN LANGID language,
+ IN StringDigitSubstitute substitute
+ )
+ {
+ return SetStatus(DllExports::GdipSetStringFormatDigitSubstitution(
+ nativeFormat,
+ language,
+ substitute
+ ));
+ }
+
+ LANGID GetDigitSubstitutionLanguage(
+ ) const
+ {
+ LANGID language;
+ SetStatus(DllExports::GdipGetStringFormatDigitSubstitution(
+ nativeFormat,
+ &language,
+ NULL
+ ));
+ return language;
+ }
+
+ StringDigitSubstitute GetDigitSubstitutionMethod(
+ ) const
+ {
+ StringDigitSubstitute substitute;
+ SetStatus(DllExports::GdipGetStringFormatDigitSubstitution(
+ nativeFormat,
+ NULL,
+ &substitute
+ ));
+ return substitute;
+ }
+#endif // DCR_USE_NEW_146933
+
+ // String trimming. How to handle more text than can be displayed
+ // in the limits available.
+
+ Status SetTrimming(IN StringTrimming trimming)
+ {
+ return SetStatus(DllExports::GdipSetStringFormatTrimming(
+ nativeFormat,
+ trimming
+ ));
+ }
+
+ StringTrimming StringFormat::GetTrimming() const
+ {
+ StringTrimming trimming;
+ SetStatus(DllExports::GdipGetStringFormatTrimming(
+ nativeFormat,
+ &trimming
+ ));
+ return trimming;
+ }
+
+#ifdef DCR_USE_NEW_174340
+ Status SetMeasurableCharacterRanges(
+ IN INT rangeCount,
+ IN const CharacterRange *ranges
+ )
+ {
+ return SetStatus(DllExports::GdipSetStringFormatMeasurableCharacterRanges(
+ nativeFormat,
+ rangeCount,
+ ranges
+ ));
+ }
+
+ INT GetMeasurableCharacterRangeCount()
+ {
+ INT count;
+ SetStatus(DllExports::GdipGetStringFormatMeasurableCharacterRangeCount(
+ nativeFormat,
+ &count
+ ));
+ return count;
+ }
+#endif
+
+ // GetLastStatus - return last error code and clear error code
+
+ Status GetLastStatus() const
+ {
+ Status lastStatus = lastError;
+ lastError = Ok;
+
+ return lastStatus;
+ }
+
+protected:
+
+ Status SetStatus(GpStatus newStatus) const
+ {
+ if (newStatus == Ok)
+ {
+ return Ok;
+ }
+ else
+ {
+ return lastError = newStatus;
+ }
+ }
+
+
+// Not allowed and move to private
+ StringFormat(const StringFormat &source)
+ {
+ nativeFormat = NULL;
+ lastError = DllExports::GdipCloneStringFormat(
+ source.nativeFormat,
+ &nativeFormat
+ );
+ }
+
+ StringFormat& operator=(const StringFormat &source)
+ {
+ DllExports::GdipDeleteStringFormat(nativeFormat);
+ lastError = DllExports::GdipCloneStringFormat(
+ source.nativeFormat,
+ &nativeFormat
+ );
+ return *this;
+ }
+
+
+ // private constructor for copy
+ StringFormat(GpStringFormat * clonedStringFormat, Status status)
+ {
+ lastError = status;
+ nativeFormat = clonedStringFormat;
+
+ }
+
+ GpStringFormat *nativeFormat;
+ mutable Status lastError;
+};
+
+// Generic constant string formats.
+
+static BYTE GenericTypographicStringFormatBuffer[sizeof(StringFormat)] = {0};
+static BYTE GenericDefaultStringFormatBuffer[sizeof(StringFormat)] = {0};
+
+static StringFormat *GenericTypographicStringFormat = NULL;
+static StringFormat *GenericDefaultStringFormat = NULL;
+
+// Define the generic string formats
+
+
+inline const StringFormat *StringFormat::GenericDefault()
+{
+ if (GenericDefaultStringFormat != NULL)
+ {
+ return GenericDefaultStringFormat;
+ }
+
+ GenericDefaultStringFormat =
+ (StringFormat*)GenericDefaultStringFormatBuffer;
+
+ GenericDefaultStringFormat->lastError =
+ DllExports::GdipStringFormatGetGenericDefault(
+ &(GenericDefaultStringFormat->nativeFormat)
+ );
+
+ return GenericDefaultStringFormat;
+}
+
+inline const StringFormat *StringFormat::GenericTypographic()
+{
+ if (GenericTypographicStringFormat != NULL)
+ {
+ return GenericTypographicStringFormat;
+ }
+
+ GenericTypographicStringFormat =
+ (StringFormat*)GenericTypographicStringFormatBuffer;
+
+ GenericTypographicStringFormat->lastError =
+ DllExports::GdipStringFormatGetGenericTypographic(
+ &GenericTypographicStringFormat->nativeFormat
+ );
+
+ return GenericTypographicStringFormat;
+}
+
+#endif // !_GDIPLUSSTRINGFORMAT_H
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusTypes.h b/core/src/fxge/Microsoft SDK/include/GdiPlusTypes.h
index 58c584dc1d..d5c03a265e 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusTypes.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusTypes.h
@@ -1,826 +1,826 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* GdiplusTypes.h
-*
-* Abstract:
-*
-* Basic types used by GDI+
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSTYPES_H
-#define _GDIPLUSTYPES_H
-
-#ifndef DCR_USE_NEW_175866
-
-//--------------------------------------------------------------------------
-// LIB version initialization functions
-//--------------------------------------------------------------------------
-
-typedef VOID (__cdecl *DEBUGEVENTFUNCTION)(INT level, CHAR *message);
-
-extern "C" BOOL __stdcall InitializeGdiplus(DEBUGEVENTFUNCTION);
-extern "C" VOID __stdcall UninitializeGdiplus();
-
-#endif
-
-//--------------------------------------------------------------------------
-// Callback functions
-//--------------------------------------------------------------------------
-
-extern "C" {
-typedef BOOL (CALLBACK * ImageAbort)(VOID *);
-typedef ImageAbort DrawImageAbort;
-typedef ImageAbort GetThumbnailImageAbort;
-}
-
-// Callback for EnumerateMetafile methods. The parameters are:
-
-// recordType WMF, EMF, or EMF+ record type
-// flags (always 0 for WMF/EMF records)
-// dataSize size of the record data (in bytes), or 0 if no data
-// data pointer to the record data, or NULL if no data
-// callbackData pointer to callbackData, if any
-
-// This method can then call Metafile::PlayRecord to play the
-// record that was just enumerated. If this method returns
-// FALSE, the enumeration process is aborted. Otherwise, it continues.
-
-extern "C" {
-typedef BOOL (CALLBACK * EnumerateMetafileProc)(EmfPlusRecordType,UINT,UINT,const BYTE*,VOID*);
-}
-
-//--------------------------------------------------------------------------
-// Primitive data types
-//
-// NOTE:
-// Types already defined in standard header files:
-// INT8
-// UINT8
-// INT16
-// UINT16
-// INT32
-// UINT32
-// INT64
-// UINT64
-//
-// Avoid using the following types:
-// LONG - use INT
-// ULONG - use UINT
-// DWORD - use UINT32
-//--------------------------------------------------------------------------
-
-typedef float REAL;
-
-#define REAL_MAX FLT_MAX
-#define REAL_MIN FLT_MIN
-#define REAL_TOLERANCE (FLT_MIN * 100)
-#define REAL_EPSILON 1.192092896e-07F /* FLT_EPSILON */
-
-//--------------------------------------------------------------------------
-// Forward declarations of various internal classes
-//--------------------------------------------------------------------------
-
-class Size;
-class SizeF;
-class Point;
-class PointF;
-class Rect;
-class RectF;
-class CharacterRange;
-
-//--------------------------------------------------------------------------
-// Return values from any GDI+ API
-//--------------------------------------------------------------------------
-
-enum Status
-{
- Ok = 0,
- GenericError = 1,
- InvalidParameter = 2,
- OutOfMemory = 3,
- ObjectBusy = 4,
- InsufficientBuffer = 5,
- NotImplemented = 6,
- Win32Error = 7,
- WrongState = 8,
- Aborted = 9,
-#ifdef DCR_USE_NEW_135429
- FileNotFound = 10,
- ValueOverflow = 11,
- AccessDenied = 12,
- UnknownImageFormat = 13,
- FontFamilyNotFound = 14,
- FontStyleNotFound = 15,
- NotTrueTypeFont = 16,
-#else
- NotFound = 10,
- ValueOverflow = 11,
-#endif
- UnsupportedGdiplusVersion = 17,
- GdiplusNotInitialized
-
-};
-
-//--------------------------------------------------------------------------
-// Represents a dimension in a 2D coordinate system
-// (floating-point coordinates)
-//--------------------------------------------------------------------------
-
-class SizeF
-{
-public:
-
- // Default constructor
- SizeF()
- {
- Width = Height = 0.0f;
- }
-
- SizeF(IN const SizeF& size)
- {
- Width = size.Width;
- Height = size.Height;
- }
-
- SizeF(IN REAL width,
- IN REAL height)
- {
- Width = width;
- Height = height;
- }
-
- SizeF operator+(IN const SizeF& sz) const
- {
- return SizeF(Width + sz.Width,
- Height + sz.Height);
- }
-
- SizeF operator-(IN const SizeF& sz) const
- {
- return SizeF(Width - sz.Width,
- Height - sz.Height);
- }
-
- BOOL Equals(IN const SizeF& sz) const
- {
- return (Width == sz.Width) && (Height == sz.Height);
- }
-
- BOOL Empty() const
- {
- return (Width == 0.0f && Height == 0.0f);
- }
-
-public:
-
- REAL Width;
- REAL Height;
-};
-
-//--------------------------------------------------------------------------
-// Represents a dimension in a 2D coordinate system
-// (integer coordinates)
-//--------------------------------------------------------------------------
-
-class Size
-{
-public:
-
- // Default constructor
- Size()
- {
- Width = Height = 0;
- }
-
- Size(IN const Size& size)
- {
- Width = size.Width;
- Height = size.Height;
- }
-
- Size(IN INT width,
- IN INT height)
- {
- Width = width;
- Height = height;
- }
-
- Size operator+(IN const Size& sz) const
- {
- return Size(Width + sz.Width,
- Height + sz.Height);
- }
-
- Size operator-(IN const Size& sz) const
- {
- return Size(Width - sz.Width,
- Height - sz.Height);
- }
-
- BOOL Equals(IN const Size& sz) const
- {
- return (Width == sz.Width) && (Height == sz.Height);
- }
-
- BOOL Empty() const
- {
- return (Width == 0 && Height == 0);
- }
-
-public:
-
- INT Width;
- INT Height;
-};
-
-//--------------------------------------------------------------------------
-// Represents a location in a 2D coordinate system
-// (floating-point coordinates)
-//--------------------------------------------------------------------------
-
-class PointF
-{
-public:
- PointF()
- {
- X = Y = 0.0f;
- }
-
- PointF(IN const PointF &point)
- {
- X = point.X;
- Y = point.Y;
- }
-
- PointF(IN const SizeF &size)
- {
- X = size.Width;
- Y = size.Height;
- }
-
- PointF(IN REAL x,
- IN REAL y)
- {
- X = x;
- Y = y;
- }
-
- PointF operator+(IN const PointF& point) const
- {
- return PointF(X + point.X,
- Y + point.Y);
- }
-
- PointF operator-(IN const PointF& point) const
- {
- return PointF(X - point.X,
- Y - point.Y);
- }
-
- BOOL Equals(IN const PointF& point)
- {
- return (X == point.X) && (Y == point.Y);
- }
-
-public:
-
- REAL X;
- REAL Y;
-};
-
-//--------------------------------------------------------------------------
-// Represents a location in a 2D coordinate system
-// (integer coordinates)
-//--------------------------------------------------------------------------
-
-class Point
-{
-public:
- Point()
- {
- X = Y = 0;
- }
-
- Point(IN const Point &point)
- {
- X = point.X;
- Y = point.Y;
- }
-
- Point(IN const Size &size)
- {
- X = size.Width;
- Y = size.Height;
- }
-
- Point(IN INT x,
- IN INT y)
- {
- X = x;
- Y = y;
- }
-
- Point operator+(IN const Point& point) const
- {
- return Point(X + point.X,
- Y + point.Y);
- }
-
- Point operator-(IN const Point& point) const
- {
- return Point(X - point.X,
- Y - point.Y);
- }
-
- BOOL Equals(IN const Point& point)
- {
- return (X == point.X) && (Y == point.Y);
- }
-
-public:
-
- INT X;
- INT Y;
-};
-
-//--------------------------------------------------------------------------
-// Represents a rectangle in a 2D coordinate system
-// (floating-point coordinates)
-//--------------------------------------------------------------------------
-
-class RectF
-{
-public:
-
- // Default constructor
-
- RectF()
- {
- X = Y = Width = Height = 0.0f;
- }
-
- RectF(IN REAL x,
- IN REAL y,
- IN REAL width,
- IN REAL height)
- {
- X = x;
- Y = y;
- Width = width;
- Height = height;
- }
-
- RectF(IN const PointF& location,
- IN const SizeF& size)
- {
- X = location.X;
- Y = location.Y;
- Width = size.Width;
- Height = size.Height;
- }
-
- RectF* Clone() const
- {
- return new RectF(X, Y, Width, Height);
- }
-
- VOID GetLocation(OUT PointF* point) const
- {
- point->X = X;
- point->Y = Y;
- }
-
- VOID GetSize(OUT SizeF* size) const
- {
- size->Width = Width;
- size->Height = Height;
- }
-
- VOID GetBounds(OUT RectF* rect) const
- {
- rect->X = X;
- rect->Y = Y;
- rect->Width = Width;
- rect->Height = Height;
- }
-
- // Return the left, top, right, and bottom
- // coordinates of the rectangle
-
- REAL GetLeft() const
- {
- return X;
- }
-
- REAL GetTop() const
- {
- return Y;
- }
-
- REAL GetRight() const
- {
- return X+Width;
- }
-
- REAL GetBottom() const
- {
- return Y+Height;
- }
-
- // Determine if the rectangle is empty
- BOOL IsEmptyArea() const
- {
- return (Width <= REAL_EPSILON) || (Height <= REAL_EPSILON);
- }
-
- BOOL Equals(IN const RectF & rect) const
- {
- return X == rect.X &&
- Y == rect.Y &&
- Width == rect.Width &&
- Height == rect.Height;
- }
-
- BOOL Contains(IN REAL x,
- IN REAL y) const
- {
- return x >= X && x < X+Width &&
- y >= Y && y < Y+Height;
- }
-
- BOOL Contains(IN const PointF& pt) const
- {
- return Contains(pt.X, pt.Y);
- }
-
- BOOL Contains(IN const RectF& rect) const
- {
- return (X <= rect.X) && (rect.GetRight() <= GetRight()) &&
- (Y <= rect.Y) && (rect.GetBottom() <= GetBottom());
- }
-
- VOID Inflate(IN REAL dx,
- IN REAL dy)
- {
- X -= dx;
- Y -= dy;
- Width += 2*dx;
- Height += 2*dy;
- }
-
- VOID Inflate(IN const PointF& point)
- {
- Inflate(point.X, point.Y);
- }
-
- // Intersect the current rect with the specified object
-
- BOOL Intersect(IN const RectF& rect)
- {
- return Intersect(*this, *this, rect);
- }
-
- // Intersect rect a and b and save the result into c
- // Notice that c may be the same object as a or b.
-
- static BOOL Intersect(OUT RectF& c,
- IN const RectF& a,
- IN const RectF& b)
- {
- REAL right = min(a.GetRight(), b.GetRight());
- REAL bottom = min(a.GetBottom(), b.GetBottom());
- REAL left = max(a.GetLeft(), b.GetLeft());
- REAL top = max(a.GetTop(), b.GetTop());
-
- c.X = left;
- c.Y = top;
- c.Width = right - left;
- c.Height = bottom - top;
- return !c.IsEmptyArea();
- }
-
- // Determine if the specified rect intersects with the
- // current rect object.
-
- BOOL IntersectsWith(IN const RectF& rect) const
- {
- return (GetLeft() < rect.GetRight() &&
- GetTop() < rect.GetTop() &&
- GetRight() > rect.GetLeft() &&
- GetBottom() > rect.GetTop());
- }
-
- static BOOL Union(OUT RectF& c,
- IN const RectF& a,
- IN const RectF& b)
- {
- REAL right = max(a.GetRight(), b.GetRight());
- REAL bottom = max(a.GetBottom(), b.GetBottom());
- REAL left = min(a.GetLeft(), b.GetLeft());
- REAL top = min(a.GetTop(), b.GetTop());
-
- c.X = left;
- c.Y = top;
- c.Width = right - left;
- c.Height = bottom - top;
- return !c.IsEmptyArea();
- }
-
- VOID Offset(IN const PointF& point)
- {
- Offset(point.X, point.Y);
- }
-
- VOID Offset(IN REAL dx,
- IN REAL dy)
- {
- X += dx;
- Y += dy;
- }
-
-public:
-
- REAL X;
- REAL Y;
- REAL Width;
- REAL Height;
-};
-
-//--------------------------------------------------------------------------
-// Represents a rectangle in a 2D coordinate system
-// (integer coordinates)
-//--------------------------------------------------------------------------
-
-class Rect
-{
-public:
-
- // Default constructor
-
- Rect()
- {
- X = Y = Width = Height = 0;
- }
-
- Rect(IN INT x,
- IN INT y,
- IN INT width,
- IN INT height)
- {
- X = x;
- Y = y;
- Width = width;
- Height = height;
- }
-
- Rect(IN const Point& location,
- IN const Size& size)
- {
- X = location.X;
- Y = location.Y;
- Width = size.Width;
- Height = size.Height;
- }
-
- Rect* Clone() const
- {
- return new Rect(X, Y, Width, Height);
- }
-
- VOID GetLocation(OUT Point* point) const
- {
- point->X = X;
- point->Y = Y;
- }
-
- VOID GetSize(OUT Size* size) const
- {
- size->Width = Width;
- size->Height = Height;
- }
-
- VOID GetBounds(OUT Rect* rect) const
- {
- rect->X = X;
- rect->Y = Y;
- rect->Width = Width;
- rect->Height = Height;
- }
-
- // Return the left, top, right, and bottom
- // coordinates of the rectangle
-
- INT GetLeft() const
- {
- return X;
- }
-
- INT GetTop() const
- {
- return Y;
- }
-
- INT GetRight() const
- {
- return X+Width;
- }
-
- INT GetBottom() const
- {
- return Y+Height;
- }
-
- // Determine if the rectangle is empty
- BOOL IsEmptyArea() const
- {
- return (Width <= 0) || (Height <= 0);
- }
-
- BOOL Equals(IN const Rect & rect) const
- {
- return X == rect.X &&
- Y == rect.Y &&
- Width == rect.Width &&
- Height == rect.Height;
- }
-
- BOOL Contains(IN INT x,
- IN INT y) const
- {
- return x >= X && x < X+Width &&
- y >= Y && y < Y+Height;
- }
-
- BOOL Contains(IN const Point& pt) const
- {
- return Contains(pt.X, pt.Y);
- }
-
- BOOL Contains(IN Rect& rect) const
- {
- return (X <= rect.X) && (rect.GetRight() <= GetRight()) &&
- (Y <= rect.Y) && (rect.GetBottom() <= GetBottom());
- }
-
- VOID Inflate(IN INT dx,
- IN INT dy)
- {
- X -= dx;
- Y -= dy;
- Width += 2*dx;
- Height += 2*dy;
- }
-
- VOID Inflate(IN const Point& point)
- {
- Inflate(point.X, point.Y);
- }
-
- // Intersect the current rect with the specified object
-
- BOOL Intersect(IN const Rect& rect)
- {
- return Intersect(*this, *this, rect);
- }
-
- // Intersect rect a and b and save the result into c
- // Notice that c may be the same object as a or b.
-
- static BOOL Intersect(OUT Rect& c,
- IN const Rect& a,
- IN const Rect& b)
- {
- INT right = min(a.GetRight(), b.GetRight());
- INT bottom = min(a.GetBottom(), b.GetBottom());
- INT left = max(a.GetLeft(), b.GetLeft());
- INT top = max(a.GetTop(), b.GetTop());
-
- c.X = left;
- c.Y = top;
- c.Width = right - left;
- c.Height = bottom - top;
- return !c.IsEmptyArea();
- }
-
- // Determine if the specified rect intersects with the
- // current rect object.
-
- BOOL IntersectsWith(IN const Rect& rect) const
- {
- return (GetLeft() < rect.GetRight() &&
- GetTop() < rect.GetTop() &&
- GetRight() > rect.GetLeft() &&
- GetBottom() > rect.GetTop());
- }
-
- static BOOL Union(OUT Rect& c,
- IN const Rect& a,
- IN const Rect& b)
- {
- INT right = max(a.GetRight(), b.GetRight());
- INT bottom = max(a.GetBottom(), b.GetBottom());
- INT left = min(a.GetLeft(), b.GetLeft());
- INT top = min(a.GetTop(), b.GetTop());
-
- c.X = left;
- c.Y = top;
- c.Width = right - left;
- c.Height = bottom - top;
- return !c.IsEmptyArea();
- }
-
- VOID Offset(IN const Point& point)
- {
- Offset(point.X, point.Y);
- }
-
- VOID Offset(IN INT dx,
- IN INT dy)
- {
- X += dx;
- Y += dy;
- }
-
-public:
-
- INT X;
- INT Y;
- INT Width;
- INT Height;
-};
-
-// A user must mange memory for PathData.
-
-class PathData
-{
-public:
- PathData()
- {
- Count = 0;
- Points = NULL;
- Types = NULL;
- }
-
- ~PathData()
- {
- if (Points != NULL)
- {
- delete Points;
- }
-
- if (Types != NULL)
- {
- delete Types;
- }
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- PathData(const PathData &);
- PathData& operator=(const PathData &);
-
-#endif
-
-public:
- INT Count;
- PointF* Points;
- BYTE* Types;
-};
-
-
-//-----------------------------
-// text character range
-//-----------------------------
-
-class CharacterRange
-{
-public:
- CharacterRange(
- INT first,
- INT length
- ) :
- First (first),
- Length (length)
- {}
-
- CharacterRange() : First(0), Length(0)
- {}
-
- CharacterRange & operator = (const CharacterRange &rhs)
- {
- First = rhs.First;
- Length = rhs.Length;
- return *this;
- }
-
- INT First;
- INT Length;
-};
-
-#endif // !_GDIPLUSTYPES_HPP
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* GdiplusTypes.h
+*
+* Abstract:
+*
+* Basic types used by GDI+
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSTYPES_H
+#define _GDIPLUSTYPES_H
+
+#ifndef DCR_USE_NEW_175866
+
+//--------------------------------------------------------------------------
+// LIB version initialization functions
+//--------------------------------------------------------------------------
+
+typedef VOID (__cdecl *DEBUGEVENTFUNCTION)(INT level, CHAR *message);
+
+extern "C" BOOL __stdcall InitializeGdiplus(DEBUGEVENTFUNCTION);
+extern "C" VOID __stdcall UninitializeGdiplus();
+
+#endif
+
+//--------------------------------------------------------------------------
+// Callback functions
+//--------------------------------------------------------------------------
+
+extern "C" {
+typedef BOOL (CALLBACK * ImageAbort)(VOID *);
+typedef ImageAbort DrawImageAbort;
+typedef ImageAbort GetThumbnailImageAbort;
+}
+
+// Callback for EnumerateMetafile methods. The parameters are:
+
+// recordType WMF, EMF, or EMF+ record type
+// flags (always 0 for WMF/EMF records)
+// dataSize size of the record data (in bytes), or 0 if no data
+// data pointer to the record data, or NULL if no data
+// callbackData pointer to callbackData, if any
+
+// This method can then call Metafile::PlayRecord to play the
+// record that was just enumerated. If this method returns
+// FALSE, the enumeration process is aborted. Otherwise, it continues.
+
+extern "C" {
+typedef BOOL (CALLBACK * EnumerateMetafileProc)(EmfPlusRecordType,UINT,UINT,const BYTE*,VOID*);
+}
+
+//--------------------------------------------------------------------------
+// Primitive data types
+//
+// NOTE:
+// Types already defined in standard header files:
+// INT8
+// UINT8
+// INT16
+// UINT16
+// INT32
+// UINT32
+// INT64
+// UINT64
+//
+// Avoid using the following types:
+// LONG - use INT
+// ULONG - use UINT
+// DWORD - use UINT32
+//--------------------------------------------------------------------------
+
+typedef float REAL;
+
+#define REAL_MAX FLT_MAX
+#define REAL_MIN FLT_MIN
+#define REAL_TOLERANCE (FLT_MIN * 100)
+#define REAL_EPSILON 1.192092896e-07F /* FLT_EPSILON */
+
+//--------------------------------------------------------------------------
+// Forward declarations of various internal classes
+//--------------------------------------------------------------------------
+
+class Size;
+class SizeF;
+class Point;
+class PointF;
+class Rect;
+class RectF;
+class CharacterRange;
+
+//--------------------------------------------------------------------------
+// Return values from any GDI+ API
+//--------------------------------------------------------------------------
+
+enum Status
+{
+ Ok = 0,
+ GenericError = 1,
+ InvalidParameter = 2,
+ OutOfMemory = 3,
+ ObjectBusy = 4,
+ InsufficientBuffer = 5,
+ NotImplemented = 6,
+ Win32Error = 7,
+ WrongState = 8,
+ Aborted = 9,
+#ifdef DCR_USE_NEW_135429
+ FileNotFound = 10,
+ ValueOverflow = 11,
+ AccessDenied = 12,
+ UnknownImageFormat = 13,
+ FontFamilyNotFound = 14,
+ FontStyleNotFound = 15,
+ NotTrueTypeFont = 16,
+#else
+ NotFound = 10,
+ ValueOverflow = 11,
+#endif
+ UnsupportedGdiplusVersion = 17,
+ GdiplusNotInitialized
+
+};
+
+//--------------------------------------------------------------------------
+// Represents a dimension in a 2D coordinate system
+// (floating-point coordinates)
+//--------------------------------------------------------------------------
+
+class SizeF
+{
+public:
+
+ // Default constructor
+ SizeF()
+ {
+ Width = Height = 0.0f;
+ }
+
+ SizeF(IN const SizeF& size)
+ {
+ Width = size.Width;
+ Height = size.Height;
+ }
+
+ SizeF(IN REAL width,
+ IN REAL height)
+ {
+ Width = width;
+ Height = height;
+ }
+
+ SizeF operator+(IN const SizeF& sz) const
+ {
+ return SizeF(Width + sz.Width,
+ Height + sz.Height);
+ }
+
+ SizeF operator-(IN const SizeF& sz) const
+ {
+ return SizeF(Width - sz.Width,
+ Height - sz.Height);
+ }
+
+ BOOL Equals(IN const SizeF& sz) const
+ {
+ return (Width == sz.Width) && (Height == sz.Height);
+ }
+
+ BOOL Empty() const
+ {
+ return (Width == 0.0f && Height == 0.0f);
+ }
+
+public:
+
+ REAL Width;
+ REAL Height;
+};
+
+//--------------------------------------------------------------------------
+// Represents a dimension in a 2D coordinate system
+// (integer coordinates)
+//--------------------------------------------------------------------------
+
+class Size
+{
+public:
+
+ // Default constructor
+ Size()
+ {
+ Width = Height = 0;
+ }
+
+ Size(IN const Size& size)
+ {
+ Width = size.Width;
+ Height = size.Height;
+ }
+
+ Size(IN INT width,
+ IN INT height)
+ {
+ Width = width;
+ Height = height;
+ }
+
+ Size operator+(IN const Size& sz) const
+ {
+ return Size(Width + sz.Width,
+ Height + sz.Height);
+ }
+
+ Size operator-(IN const Size& sz) const
+ {
+ return Size(Width - sz.Width,
+ Height - sz.Height);
+ }
+
+ BOOL Equals(IN const Size& sz) const
+ {
+ return (Width == sz.Width) && (Height == sz.Height);
+ }
+
+ BOOL Empty() const
+ {
+ return (Width == 0 && Height == 0);
+ }
+
+public:
+
+ INT Width;
+ INT Height;
+};
+
+//--------------------------------------------------------------------------
+// Represents a location in a 2D coordinate system
+// (floating-point coordinates)
+//--------------------------------------------------------------------------
+
+class PointF
+{
+public:
+ PointF()
+ {
+ X = Y = 0.0f;
+ }
+
+ PointF(IN const PointF &point)
+ {
+ X = point.X;
+ Y = point.Y;
+ }
+
+ PointF(IN const SizeF &size)
+ {
+ X = size.Width;
+ Y = size.Height;
+ }
+
+ PointF(IN REAL x,
+ IN REAL y)
+ {
+ X = x;
+ Y = y;
+ }
+
+ PointF operator+(IN const PointF& point) const
+ {
+ return PointF(X + point.X,
+ Y + point.Y);
+ }
+
+ PointF operator-(IN const PointF& point) const
+ {
+ return PointF(X - point.X,
+ Y - point.Y);
+ }
+
+ BOOL Equals(IN const PointF& point)
+ {
+ return (X == point.X) && (Y == point.Y);
+ }
+
+public:
+
+ REAL X;
+ REAL Y;
+};
+
+//--------------------------------------------------------------------------
+// Represents a location in a 2D coordinate system
+// (integer coordinates)
+//--------------------------------------------------------------------------
+
+class Point
+{
+public:
+ Point()
+ {
+ X = Y = 0;
+ }
+
+ Point(IN const Point &point)
+ {
+ X = point.X;
+ Y = point.Y;
+ }
+
+ Point(IN const Size &size)
+ {
+ X = size.Width;
+ Y = size.Height;
+ }
+
+ Point(IN INT x,
+ IN INT y)
+ {
+ X = x;
+ Y = y;
+ }
+
+ Point operator+(IN const Point& point) const
+ {
+ return Point(X + point.X,
+ Y + point.Y);
+ }
+
+ Point operator-(IN const Point& point) const
+ {
+ return Point(X - point.X,
+ Y - point.Y);
+ }
+
+ BOOL Equals(IN const Point& point)
+ {
+ return (X == point.X) && (Y == point.Y);
+ }
+
+public:
+
+ INT X;
+ INT Y;
+};
+
+//--------------------------------------------------------------------------
+// Represents a rectangle in a 2D coordinate system
+// (floating-point coordinates)
+//--------------------------------------------------------------------------
+
+class RectF
+{
+public:
+
+ // Default constructor
+
+ RectF()
+ {
+ X = Y = Width = Height = 0.0f;
+ }
+
+ RectF(IN REAL x,
+ IN REAL y,
+ IN REAL width,
+ IN REAL height)
+ {
+ X = x;
+ Y = y;
+ Width = width;
+ Height = height;
+ }
+
+ RectF(IN const PointF& location,
+ IN const SizeF& size)
+ {
+ X = location.X;
+ Y = location.Y;
+ Width = size.Width;
+ Height = size.Height;
+ }
+
+ RectF* Clone() const
+ {
+ return new RectF(X, Y, Width, Height);
+ }
+
+ VOID GetLocation(OUT PointF* point) const
+ {
+ point->X = X;
+ point->Y = Y;
+ }
+
+ VOID GetSize(OUT SizeF* size) const
+ {
+ size->Width = Width;
+ size->Height = Height;
+ }
+
+ VOID GetBounds(OUT RectF* rect) const
+ {
+ rect->X = X;
+ rect->Y = Y;
+ rect->Width = Width;
+ rect->Height = Height;
+ }
+
+ // Return the left, top, right, and bottom
+ // coordinates of the rectangle
+
+ REAL GetLeft() const
+ {
+ return X;
+ }
+
+ REAL GetTop() const
+ {
+ return Y;
+ }
+
+ REAL GetRight() const
+ {
+ return X+Width;
+ }
+
+ REAL GetBottom() const
+ {
+ return Y+Height;
+ }
+
+ // Determine if the rectangle is empty
+ BOOL IsEmptyArea() const
+ {
+ return (Width <= REAL_EPSILON) || (Height <= REAL_EPSILON);
+ }
+
+ BOOL Equals(IN const RectF & rect) const
+ {
+ return X == rect.X &&
+ Y == rect.Y &&
+ Width == rect.Width &&
+ Height == rect.Height;
+ }
+
+ BOOL Contains(IN REAL x,
+ IN REAL y) const
+ {
+ return x >= X && x < X+Width &&
+ y >= Y && y < Y+Height;
+ }
+
+ BOOL Contains(IN const PointF& pt) const
+ {
+ return Contains(pt.X, pt.Y);
+ }
+
+ BOOL Contains(IN const RectF& rect) const
+ {
+ return (X <= rect.X) && (rect.GetRight() <= GetRight()) &&
+ (Y <= rect.Y) && (rect.GetBottom() <= GetBottom());
+ }
+
+ VOID Inflate(IN REAL dx,
+ IN REAL dy)
+ {
+ X -= dx;
+ Y -= dy;
+ Width += 2*dx;
+ Height += 2*dy;
+ }
+
+ VOID Inflate(IN const PointF& point)
+ {
+ Inflate(point.X, point.Y);
+ }
+
+ // Intersect the current rect with the specified object
+
+ BOOL Intersect(IN const RectF& rect)
+ {
+ return Intersect(*this, *this, rect);
+ }
+
+ // Intersect rect a and b and save the result into c
+ // Notice that c may be the same object as a or b.
+
+ static BOOL Intersect(OUT RectF& c,
+ IN const RectF& a,
+ IN const RectF& b)
+ {
+ REAL right = min(a.GetRight(), b.GetRight());
+ REAL bottom = min(a.GetBottom(), b.GetBottom());
+ REAL left = max(a.GetLeft(), b.GetLeft());
+ REAL top = max(a.GetTop(), b.GetTop());
+
+ c.X = left;
+ c.Y = top;
+ c.Width = right - left;
+ c.Height = bottom - top;
+ return !c.IsEmptyArea();
+ }
+
+ // Determine if the specified rect intersects with the
+ // current rect object.
+
+ BOOL IntersectsWith(IN const RectF& rect) const
+ {
+ return (GetLeft() < rect.GetRight() &&
+ GetTop() < rect.GetTop() &&
+ GetRight() > rect.GetLeft() &&
+ GetBottom() > rect.GetTop());
+ }
+
+ static BOOL Union(OUT RectF& c,
+ IN const RectF& a,
+ IN const RectF& b)
+ {
+ REAL right = max(a.GetRight(), b.GetRight());
+ REAL bottom = max(a.GetBottom(), b.GetBottom());
+ REAL left = min(a.GetLeft(), b.GetLeft());
+ REAL top = min(a.GetTop(), b.GetTop());
+
+ c.X = left;
+ c.Y = top;
+ c.Width = right - left;
+ c.Height = bottom - top;
+ return !c.IsEmptyArea();
+ }
+
+ VOID Offset(IN const PointF& point)
+ {
+ Offset(point.X, point.Y);
+ }
+
+ VOID Offset(IN REAL dx,
+ IN REAL dy)
+ {
+ X += dx;
+ Y += dy;
+ }
+
+public:
+
+ REAL X;
+ REAL Y;
+ REAL Width;
+ REAL Height;
+};
+
+//--------------------------------------------------------------------------
+// Represents a rectangle in a 2D coordinate system
+// (integer coordinates)
+//--------------------------------------------------------------------------
+
+class Rect
+{
+public:
+
+ // Default constructor
+
+ Rect()
+ {
+ X = Y = Width = Height = 0;
+ }
+
+ Rect(IN INT x,
+ IN INT y,
+ IN INT width,
+ IN INT height)
+ {
+ X = x;
+ Y = y;
+ Width = width;
+ Height = height;
+ }
+
+ Rect(IN const Point& location,
+ IN const Size& size)
+ {
+ X = location.X;
+ Y = location.Y;
+ Width = size.Width;
+ Height = size.Height;
+ }
+
+ Rect* Clone() const
+ {
+ return new Rect(X, Y, Width, Height);
+ }
+
+ VOID GetLocation(OUT Point* point) const
+ {
+ point->X = X;
+ point->Y = Y;
+ }
+
+ VOID GetSize(OUT Size* size) const
+ {
+ size->Width = Width;
+ size->Height = Height;
+ }
+
+ VOID GetBounds(OUT Rect* rect) const
+ {
+ rect->X = X;
+ rect->Y = Y;
+ rect->Width = Width;
+ rect->Height = Height;
+ }
+
+ // Return the left, top, right, and bottom
+ // coordinates of the rectangle
+
+ INT GetLeft() const
+ {
+ return X;
+ }
+
+ INT GetTop() const
+ {
+ return Y;
+ }
+
+ INT GetRight() const
+ {
+ return X+Width;
+ }
+
+ INT GetBottom() const
+ {
+ return Y+Height;
+ }
+
+ // Determine if the rectangle is empty
+ BOOL IsEmptyArea() const
+ {
+ return (Width <= 0) || (Height <= 0);
+ }
+
+ BOOL Equals(IN const Rect & rect) const
+ {
+ return X == rect.X &&
+ Y == rect.Y &&
+ Width == rect.Width &&
+ Height == rect.Height;
+ }
+
+ BOOL Contains(IN INT x,
+ IN INT y) const
+ {
+ return x >= X && x < X+Width &&
+ y >= Y && y < Y+Height;
+ }
+
+ BOOL Contains(IN const Point& pt) const
+ {
+ return Contains(pt.X, pt.Y);
+ }
+
+ BOOL Contains(IN Rect& rect) const
+ {
+ return (X <= rect.X) && (rect.GetRight() <= GetRight()) &&
+ (Y <= rect.Y) && (rect.GetBottom() <= GetBottom());
+ }
+
+ VOID Inflate(IN INT dx,
+ IN INT dy)
+ {
+ X -= dx;
+ Y -= dy;
+ Width += 2*dx;
+ Height += 2*dy;
+ }
+
+ VOID Inflate(IN const Point& point)
+ {
+ Inflate(point.X, point.Y);
+ }
+
+ // Intersect the current rect with the specified object
+
+ BOOL Intersect(IN const Rect& rect)
+ {
+ return Intersect(*this, *this, rect);
+ }
+
+ // Intersect rect a and b and save the result into c
+ // Notice that c may be the same object as a or b.
+
+ static BOOL Intersect(OUT Rect& c,
+ IN const Rect& a,
+ IN const Rect& b)
+ {
+ INT right = min(a.GetRight(), b.GetRight());
+ INT bottom = min(a.GetBottom(), b.GetBottom());
+ INT left = max(a.GetLeft(), b.GetLeft());
+ INT top = max(a.GetTop(), b.GetTop());
+
+ c.X = left;
+ c.Y = top;
+ c.Width = right - left;
+ c.Height = bottom - top;
+ return !c.IsEmptyArea();
+ }
+
+ // Determine if the specified rect intersects with the
+ // current rect object.
+
+ BOOL IntersectsWith(IN const Rect& rect) const
+ {
+ return (GetLeft() < rect.GetRight() &&
+ GetTop() < rect.GetTop() &&
+ GetRight() > rect.GetLeft() &&
+ GetBottom() > rect.GetTop());
+ }
+
+ static BOOL Union(OUT Rect& c,
+ IN const Rect& a,
+ IN const Rect& b)
+ {
+ INT right = max(a.GetRight(), b.GetRight());
+ INT bottom = max(a.GetBottom(), b.GetBottom());
+ INT left = min(a.GetLeft(), b.GetLeft());
+ INT top = min(a.GetTop(), b.GetTop());
+
+ c.X = left;
+ c.Y = top;
+ c.Width = right - left;
+ c.Height = bottom - top;
+ return !c.IsEmptyArea();
+ }
+
+ VOID Offset(IN const Point& point)
+ {
+ Offset(point.X, point.Y);
+ }
+
+ VOID Offset(IN INT dx,
+ IN INT dy)
+ {
+ X += dx;
+ Y += dy;
+ }
+
+public:
+
+ INT X;
+ INT Y;
+ INT Width;
+ INT Height;
+};
+
+// A user must mange memory for PathData.
+
+class PathData
+{
+public:
+ PathData()
+ {
+ Count = 0;
+ Points = NULL;
+ Types = NULL;
+ }
+
+ ~PathData()
+ {
+ if (Points != NULL)
+ {
+ delete Points;
+ }
+
+ if (Types != NULL)
+ {
+ delete Types;
+ }
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ PathData(const PathData &);
+ PathData& operator=(const PathData &);
+
+#endif
+
+public:
+ INT Count;
+ PointF* Points;
+ BYTE* Types;
+};
+
+
+//-----------------------------
+// text character range
+//-----------------------------
+
+class CharacterRange
+{
+public:
+ CharacterRange(
+ INT first,
+ INT length
+ ) :
+ First (first),
+ Length (length)
+ {}
+
+ CharacterRange() : First(0), Length(0)
+ {}
+
+ CharacterRange & operator = (const CharacterRange &rhs)
+ {
+ First = rhs.First;
+ Length = rhs.Length;
+ return *this;
+ }
+
+ INT First;
+ INT Length;
+};
+
+#endif // !_GDIPLUSTYPES_HPP
diff --git a/core/src/fxge/Microsoft SDK/include/GdiPlusimageAttributes.h b/core/src/fxge/Microsoft SDK/include/GdiPlusimageAttributes.h
index 0a514772bc..26da28c756 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiPlusimageAttributes.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiPlusimageAttributes.h
@@ -1,397 +1,397 @@
-/**************************************************************************\
-*
-* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
-*
-* Module Name:
-*
-* Image Attributes
-*
-* Abstract:
-*
-* Class for color adjustment object passed to Graphics.DrawImage
-*
-\**************************************************************************/
-
-#ifndef _GDIPLUSIMAGEATTRIBUTES_H
-#define _GDIPLUSIMAGEATTRIBUTES_H
-
-class GpImageAttributes;
-
-// There are 5 possible sets of color adjustments:
-// ColorAdjustDefault,
-// ColorAdjustBitmap,
-// ColorAdjustBrush,
-// ColorAdjustPen,
-// ColorAdjustText,
-
-// Bitmaps, Brushes, Pens, and Text will all use any color adjustments
-// that have been set into the default ImageAttributes until their own
-// color adjustments have been set. So as soon as any "Set" method is
-// called for Bitmaps, Brushes, Pens, or Text, then they start from
-// scratch with only the color adjustments that have been set for them.
-// Calling Reset removes any individual color adjustments for a type
-// and makes it revert back to using all the default color adjustments
-// (if any). The SetToIdentity method is a way to force a type to
-// have no color adjustments at all, regardless of what previous adjustments
-// have been set for the defaults or for that type.
-
-class ImageAttributes : public GdiplusBase
-{
- friend class Graphics;
- friend class TextureBrush;
-
-public:
-
- ImageAttributes()
- {
- nativeImageAttr = NULL;
- lastResult = DllExports::GdipCreateImageAttributes(&nativeImageAttr);
- }
-
- ~ImageAttributes()
- {
- DllExports::GdipDisposeImageAttributes(nativeImageAttr);
- }
-
- ImageAttributes* Clone() const
- {
- GpImageAttributes* clone;
-
- SetStatus(DllExports::GdipCloneImageAttributes(
- nativeImageAttr,
- &clone));
-
- return new ImageAttributes(clone, lastResult);
- }
-
- // Set to identity, regardless of what the default color adjustment is.
- Status
- SetToIdentity(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesToIdentity(
- nativeImageAttr,
- type));
- }
-
- // Remove any individual color adjustments, and go back to using the default
- Status
- Reset(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipResetImageAttributes(
- nativeImageAttr,
- type));
- }
-
- Status
- SetColorMatrix(
- IN const ColorMatrix *colorMatrix,
- IN ColorMatrixFlags mode = ColorMatrixFlagsDefault,
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesColorMatrix(
- nativeImageAttr,
- type,
- TRUE,
- colorMatrix,
- NULL,
- mode));
- }
-
- Status ClearColorMatrix(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesColorMatrix(
- nativeImageAttr,
- type,
- FALSE,
- NULL,
- NULL,
- ColorMatrixFlagsDefault));
- }
-
- Status
- SetColorMatrices(
- IN const ColorMatrix *colorMatrix,
- IN const ColorMatrix *grayMatrix,
- IN ColorMatrixFlags mode = ColorMatrixFlagsDefault,
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesColorMatrix(
- nativeImageAttr,
- type,
- TRUE,
- colorMatrix,
- grayMatrix,
- mode));
- }
-
- Status ClearColorMatrices(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesColorMatrix(
- nativeImageAttr,
- type,
- FALSE,
- NULL,
- NULL,
- ColorMatrixFlagsDefault));
- }
-
- Status SetThreshold(
- IN REAL threshold,
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesThreshold(
- nativeImageAttr,
- type,
- TRUE,
- threshold));
- }
-
- Status ClearThreshold(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesThreshold(
- nativeImageAttr,
- type,
- FALSE,
- 0.0));
- }
-
- Status SetGamma(
- IN REAL gamma,
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesGamma(
- nativeImageAttr,
- type,
- TRUE,
- gamma));
- }
-
- Status ClearGamma(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesGamma(
- nativeImageAttr,
- type,
- FALSE,
- 0.0));
- }
-
- Status SetNoOp(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesNoOp(
- nativeImageAttr,
- type,
- TRUE));
- }
-
- Status ClearNoOp(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesNoOp(
- nativeImageAttr,
- type,
- FALSE));
- }
-
- Status SetColorKey(
- IN const Color& colorLow,
- IN const Color& colorHigh,
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesColorKeys(
- nativeImageAttr,
- type,
- TRUE,
- colorLow.GetValue(),
- colorHigh.GetValue()));
- }
-
- Status ClearColorKey(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesColorKeys(
- nativeImageAttr,
- type,
- FALSE,
- NULL,
- NULL));
- }
-
- Status SetOutputChannel(
- IN ColorChannelFlags channelFlags,
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesOutputChannel(
- nativeImageAttr,
- type,
- TRUE,
- channelFlags));
- }
-
- Status ClearOutputChannel(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesOutputChannel(
- nativeImageAttr,
- type,
- FALSE,
- ColorChannelFlagsLast));
- }
-
- Status SetOutputChannelColorProfile(
- IN const WCHAR *colorProfileFilename,
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesOutputChannelColorProfile(
- nativeImageAttr,
- type,
- TRUE,
- colorProfileFilename));
- }
-
- Status ClearOutputChannelColorProfile(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesOutputChannelColorProfile(
- nativeImageAttr,
- type,
- FALSE,
- NULL));
- }
-
- Status SetRemapTable(
- IN UINT mapSize,
- IN const ColorMap *map,
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesRemapTable(
- nativeImageAttr,
- type,
- TRUE,
- mapSize,
- map));
- }
-
- Status ClearRemapTable(
- IN ColorAdjustType type = ColorAdjustTypeDefault
- )
- {
- return SetStatus(DllExports::GdipSetImageAttributesRemapTable(
- nativeImageAttr,
- type,
- FALSE,
- 0,
- NULL));
- }
-
- Status SetBrushRemapTable(IN UINT mapSize,
- IN const ColorMap *map)
- {
- return this->SetRemapTable(mapSize, map, ColorAdjustTypeBrush);
- }
-
- Status ClearBrushRemapTable()
- {
- return this->ClearRemapTable(ColorAdjustTypeBrush);
- }
-
- Status SetWrapMode(IN WrapMode wrap,
- IN const Color& color = Color(),
- IN BOOL clamp = FALSE)
- {
- ARGB argb = color.GetValue();
-
- return SetStatus(DllExports::GdipSetImageAttributesWrapMode(
- nativeImageAttr, wrap, argb, clamp));
- }
-
- #ifndef DCR_USE_NEW_145139
- Status SetICMMode(IN BOOL on)
- {
- on;
- // This is not implemented.
- // The supported method for doing ICM conversion from the embedded
- // ICC profile is to use the Bitmap constructor from a file or stream
- // and specify TRUE for the useIcm parameter. This will cause the
- // image to be ICM converted when it's loaded from the file/stream
- // if the profile exists.
- return SetStatus(NotImplemented);
-// DllExports::GdipSetImageAttributesICMMode(nativeImageAttr, on)
- }
- #endif
-
- // The flags of the palette are ignored.
- Status GetAdjustedPalette(IN OUT ColorPalette* colorPalette,
- IN ColorAdjustType colorAdjustType) const
- {
- return SetStatus(DllExports::GdipGetImageAttributesAdjustedPalette(
- nativeImageAttr, colorPalette, colorAdjustType));
- }
-
- Status GetLastStatus() const
- {
- Status lastStatus = lastResult;
- lastResult = Ok;
-
- return lastStatus;
- }
-
-#ifdef DCR_USE_NEW_250932
-
-private:
- ImageAttributes(const ImageAttributes &);
- ImageAttributes& operator=(const ImageAttributes &);
-
-#endif
-
-protected:
- ImageAttributes(GpImageAttributes* imageAttr, Status status)
- {
- SetNativeImageAttr(imageAttr);
- lastResult = status;
- }
-
- VOID SetNativeImageAttr(GpImageAttributes* nativeImageAttr)
- {
- this->nativeImageAttr = nativeImageAttr;
- }
-
- Status SetStatus(Status status) const
- {
- if (status != Ok)
- return (lastResult = status);
- else
- return status;
- }
-
-protected:
- GpImageAttributes* nativeImageAttr;
- mutable Status lastResult;
-};
-
-#endif
+/**************************************************************************\
+*
+* Copyright (c) 1998-2000, Microsoft Corp. All Rights Reserved.
+*
+* Module Name:
+*
+* Image Attributes
+*
+* Abstract:
+*
+* Class for color adjustment object passed to Graphics.DrawImage
+*
+\**************************************************************************/
+
+#ifndef _GDIPLUSIMAGEATTRIBUTES_H
+#define _GDIPLUSIMAGEATTRIBUTES_H
+
+class GpImageAttributes;
+
+// There are 5 possible sets of color adjustments:
+// ColorAdjustDefault,
+// ColorAdjustBitmap,
+// ColorAdjustBrush,
+// ColorAdjustPen,
+// ColorAdjustText,
+
+// Bitmaps, Brushes, Pens, and Text will all use any color adjustments
+// that have been set into the default ImageAttributes until their own
+// color adjustments have been set. So as soon as any "Set" method is
+// called for Bitmaps, Brushes, Pens, or Text, then they start from
+// scratch with only the color adjustments that have been set for them.
+// Calling Reset removes any individual color adjustments for a type
+// and makes it revert back to using all the default color adjustments
+// (if any). The SetToIdentity method is a way to force a type to
+// have no color adjustments at all, regardless of what previous adjustments
+// have been set for the defaults or for that type.
+
+class ImageAttributes : public GdiplusBase
+{
+ friend class Graphics;
+ friend class TextureBrush;
+
+public:
+
+ ImageAttributes()
+ {
+ nativeImageAttr = NULL;
+ lastResult = DllExports::GdipCreateImageAttributes(&nativeImageAttr);
+ }
+
+ ~ImageAttributes()
+ {
+ DllExports::GdipDisposeImageAttributes(nativeImageAttr);
+ }
+
+ ImageAttributes* Clone() const
+ {
+ GpImageAttributes* clone;
+
+ SetStatus(DllExports::GdipCloneImageAttributes(
+ nativeImageAttr,
+ &clone));
+
+ return new ImageAttributes(clone, lastResult);
+ }
+
+ // Set to identity, regardless of what the default color adjustment is.
+ Status
+ SetToIdentity(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesToIdentity(
+ nativeImageAttr,
+ type));
+ }
+
+ // Remove any individual color adjustments, and go back to using the default
+ Status
+ Reset(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipResetImageAttributes(
+ nativeImageAttr,
+ type));
+ }
+
+ Status
+ SetColorMatrix(
+ IN const ColorMatrix *colorMatrix,
+ IN ColorMatrixFlags mode = ColorMatrixFlagsDefault,
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesColorMatrix(
+ nativeImageAttr,
+ type,
+ TRUE,
+ colorMatrix,
+ NULL,
+ mode));
+ }
+
+ Status ClearColorMatrix(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesColorMatrix(
+ nativeImageAttr,
+ type,
+ FALSE,
+ NULL,
+ NULL,
+ ColorMatrixFlagsDefault));
+ }
+
+ Status
+ SetColorMatrices(
+ IN const ColorMatrix *colorMatrix,
+ IN const ColorMatrix *grayMatrix,
+ IN ColorMatrixFlags mode = ColorMatrixFlagsDefault,
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesColorMatrix(
+ nativeImageAttr,
+ type,
+ TRUE,
+ colorMatrix,
+ grayMatrix,
+ mode));
+ }
+
+ Status ClearColorMatrices(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesColorMatrix(
+ nativeImageAttr,
+ type,
+ FALSE,
+ NULL,
+ NULL,
+ ColorMatrixFlagsDefault));
+ }
+
+ Status SetThreshold(
+ IN REAL threshold,
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesThreshold(
+ nativeImageAttr,
+ type,
+ TRUE,
+ threshold));
+ }
+
+ Status ClearThreshold(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesThreshold(
+ nativeImageAttr,
+ type,
+ FALSE,
+ 0.0));
+ }
+
+ Status SetGamma(
+ IN REAL gamma,
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesGamma(
+ nativeImageAttr,
+ type,
+ TRUE,
+ gamma));
+ }
+
+ Status ClearGamma(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesGamma(
+ nativeImageAttr,
+ type,
+ FALSE,
+ 0.0));
+ }
+
+ Status SetNoOp(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesNoOp(
+ nativeImageAttr,
+ type,
+ TRUE));
+ }
+
+ Status ClearNoOp(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesNoOp(
+ nativeImageAttr,
+ type,
+ FALSE));
+ }
+
+ Status SetColorKey(
+ IN const Color& colorLow,
+ IN const Color& colorHigh,
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesColorKeys(
+ nativeImageAttr,
+ type,
+ TRUE,
+ colorLow.GetValue(),
+ colorHigh.GetValue()));
+ }
+
+ Status ClearColorKey(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesColorKeys(
+ nativeImageAttr,
+ type,
+ FALSE,
+ NULL,
+ NULL));
+ }
+
+ Status SetOutputChannel(
+ IN ColorChannelFlags channelFlags,
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesOutputChannel(
+ nativeImageAttr,
+ type,
+ TRUE,
+ channelFlags));
+ }
+
+ Status ClearOutputChannel(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesOutputChannel(
+ nativeImageAttr,
+ type,
+ FALSE,
+ ColorChannelFlagsLast));
+ }
+
+ Status SetOutputChannelColorProfile(
+ IN const WCHAR *colorProfileFilename,
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesOutputChannelColorProfile(
+ nativeImageAttr,
+ type,
+ TRUE,
+ colorProfileFilename));
+ }
+
+ Status ClearOutputChannelColorProfile(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesOutputChannelColorProfile(
+ nativeImageAttr,
+ type,
+ FALSE,
+ NULL));
+ }
+
+ Status SetRemapTable(
+ IN UINT mapSize,
+ IN const ColorMap *map,
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesRemapTable(
+ nativeImageAttr,
+ type,
+ TRUE,
+ mapSize,
+ map));
+ }
+
+ Status ClearRemapTable(
+ IN ColorAdjustType type = ColorAdjustTypeDefault
+ )
+ {
+ return SetStatus(DllExports::GdipSetImageAttributesRemapTable(
+ nativeImageAttr,
+ type,
+ FALSE,
+ 0,
+ NULL));
+ }
+
+ Status SetBrushRemapTable(IN UINT mapSize,
+ IN const ColorMap *map)
+ {
+ return this->SetRemapTable(mapSize, map, ColorAdjustTypeBrush);
+ }
+
+ Status ClearBrushRemapTable()
+ {
+ return this->ClearRemapTable(ColorAdjustTypeBrush);
+ }
+
+ Status SetWrapMode(IN WrapMode wrap,
+ IN const Color& color = Color(),
+ IN BOOL clamp = FALSE)
+ {
+ ARGB argb = color.GetValue();
+
+ return SetStatus(DllExports::GdipSetImageAttributesWrapMode(
+ nativeImageAttr, wrap, argb, clamp));
+ }
+
+ #ifndef DCR_USE_NEW_145139
+ Status SetICMMode(IN BOOL on)
+ {
+ on;
+ // This is not implemented.
+ // The supported method for doing ICM conversion from the embedded
+ // ICC profile is to use the Bitmap constructor from a file or stream
+ // and specify TRUE for the useIcm parameter. This will cause the
+ // image to be ICM converted when it's loaded from the file/stream
+ // if the profile exists.
+ return SetStatus(NotImplemented);
+// DllExports::GdipSetImageAttributesICMMode(nativeImageAttr, on)
+ }
+ #endif
+
+ // The flags of the palette are ignored.
+ Status GetAdjustedPalette(IN OUT ColorPalette* colorPalette,
+ IN ColorAdjustType colorAdjustType) const
+ {
+ return SetStatus(DllExports::GdipGetImageAttributesAdjustedPalette(
+ nativeImageAttr, colorPalette, colorAdjustType));
+ }
+
+ Status GetLastStatus() const
+ {
+ Status lastStatus = lastResult;
+ lastResult = Ok;
+
+ return lastStatus;
+ }
+
+#ifdef DCR_USE_NEW_250932
+
+private:
+ ImageAttributes(const ImageAttributes &);
+ ImageAttributes& operator=(const ImageAttributes &);
+
+#endif
+
+protected:
+ ImageAttributes(GpImageAttributes* imageAttr, Status status)
+ {
+ SetNativeImageAttr(imageAttr);
+ lastResult = status;
+ }
+
+ VOID SetNativeImageAttr(GpImageAttributes* nativeImageAttr)
+ {
+ this->nativeImageAttr = nativeImageAttr;
+ }
+
+ Status SetStatus(Status status) const
+ {
+ if (status != Ok)
+ return (lastResult = status);
+ else
+ return status;
+ }
+
+protected:
+ GpImageAttributes* nativeImageAttr;
+ mutable Status lastResult;
+};
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/GdiplusInit.h b/core/src/fxge/Microsoft SDK/include/GdiplusInit.h
index 3320fa4b7e..48516d63d5 100644
--- a/core/src/fxge/Microsoft SDK/include/GdiplusInit.h
+++ b/core/src/fxge/Microsoft SDK/include/GdiplusInit.h
@@ -1,104 +1,104 @@
-/**************************************************************************
-*
-* Copyright (c) 2000 Microsoft Corporation
-*
-* Module Name:
-*
-* Gdiplus init
-*
-* Abstract:
-*
-* GDI+ startup/shutdown API's
-*
-* Created:
-*
-* 09/02/2000 agodfrey
-* Created it.
-*
-**************************************************************************/
-
-#ifndef _GDIPLUSINIT_H
-#define _GDIPLUSINIT_H
-//************************************************************************
-#if _FX_COMPILER_ == _FX_VC6_
-typedef unsigned long ULONG_PTR, *PULONG_PTR; //johnson add here.
-#endif
-//************************************************************************
-
-// Used for debug event notification (debug builds only)
-
-enum DebugEventLevel
-{
- DebugEventLevelFatal,
- DebugEventLevelWarning
-};
-
-// Callback function that GDI+ can call, on debug builds, for assertions
-// and warnings.
-
-typedef VOID (WINAPI *DebugEventProc)(DebugEventLevel level, CHAR *message);
-
-// Notification functions which the user must call appropriately if
-// "SuppressBackgroundThread" (below) is set.
-
-typedef Status (WINAPI *NotificationHookProc)(OUT ULONG_PTR *token);
-typedef VOID (WINAPI *NotificationUnhookProc)(ULONG_PTR token);
-
-// Input structure for GdiplusStartup()
-
-struct GdiplusStartupInput
-{
- UINT32 GdiplusVersion; // Must be 1
- DebugEventProc DebugEventCallback; // Ignored on free builds
- BOOL SuppressBackgroundThread; // FALSE unless you're prepared to call
- // the hook/unhook functions properly
- BOOL SuppressExternalCodecs; // FALSE unless you want GDI+ only to use
- // its internal image codecs.
-
- GdiplusStartupInput(
- DebugEventProc debugEventCallback = NULL,
- BOOL suppressBackgroundThread = FALSE,
- BOOL suppressExternalCodecs = FALSE)
- {
- GdiplusVersion = 1;
- DebugEventCallback = debugEventCallback;
- SuppressBackgroundThread = suppressBackgroundThread;
- SuppressExternalCodecs = suppressExternalCodecs;
- }
-};
-
-// Output structure for GdiplusStartup()
-
-struct GdiplusStartupOutput
-{
- // The following 2 fields are NULL if SuppressBackgroundThread is FALSE.
- // Otherwise, they are functions which must be called appropriately to
- // replace the background thread.
- //
- // These should be called on the application's main message loop - i.e.
- // a message loop which is active for the lifetime of GDI+.
- // "NotificationHook" should be called before starting the loop,
- // and "NotificationUnhook" should be called after the loop ends.
-
- NotificationHookProc NotificationHook;
- NotificationUnhookProc NotificationUnhook;
-};
-
-// GDI+ initialization. Must be called before GDI+ API's are used.
-//
-// token - may not be NULL - accepts a token to be passed in the corresponding
-// GdiplusShutdown call.
-// input - may not be NULL
-// output - may be NULL only if input->SuppressBackgroundThread is FALSE.
-
-extern "C" Status WINAPI GdiplusStartup(
- OUT ULONG_PTR *token,
- const GdiplusStartupInput *input,
- OUT GdiplusStartupOutput *output);
-
-// GDI+ termination. Must be called before GDI+ is unloaded. GDI+ API's may not
-// be called after this.
-
-extern "C" VOID WINAPI GdiplusShutdown(ULONG_PTR token);
-
-#endif
+/**************************************************************************
+*
+* Copyright (c) 2000 Microsoft Corporation
+*
+* Module Name:
+*
+* Gdiplus init
+*
+* Abstract:
+*
+* GDI+ startup/shutdown API's
+*
+* Created:
+*
+* 09/02/2000 agodfrey
+* Created it.
+*
+**************************************************************************/
+
+#ifndef _GDIPLUSINIT_H
+#define _GDIPLUSINIT_H
+//************************************************************************
+#if _FX_COMPILER_ == _FX_VC6_
+typedef unsigned long ULONG_PTR, *PULONG_PTR; //johnson add here.
+#endif
+//************************************************************************
+
+// Used for debug event notification (debug builds only)
+
+enum DebugEventLevel
+{
+ DebugEventLevelFatal,
+ DebugEventLevelWarning
+};
+
+// Callback function that GDI+ can call, on debug builds, for assertions
+// and warnings.
+
+typedef VOID (WINAPI *DebugEventProc)(DebugEventLevel level, CHAR *message);
+
+// Notification functions which the user must call appropriately if
+// "SuppressBackgroundThread" (below) is set.
+
+typedef Status (WINAPI *NotificationHookProc)(OUT ULONG_PTR *token);
+typedef VOID (WINAPI *NotificationUnhookProc)(ULONG_PTR token);
+
+// Input structure for GdiplusStartup()
+
+struct GdiplusStartupInput
+{
+ UINT32 GdiplusVersion; // Must be 1
+ DebugEventProc DebugEventCallback; // Ignored on free builds
+ BOOL SuppressBackgroundThread; // FALSE unless you're prepared to call
+ // the hook/unhook functions properly
+ BOOL SuppressExternalCodecs; // FALSE unless you want GDI+ only to use
+ // its internal image codecs.
+
+ GdiplusStartupInput(
+ DebugEventProc debugEventCallback = NULL,
+ BOOL suppressBackgroundThread = FALSE,
+ BOOL suppressExternalCodecs = FALSE)
+ {
+ GdiplusVersion = 1;
+ DebugEventCallback = debugEventCallback;
+ SuppressBackgroundThread = suppressBackgroundThread;
+ SuppressExternalCodecs = suppressExternalCodecs;
+ }
+};
+
+// Output structure for GdiplusStartup()
+
+struct GdiplusStartupOutput
+{
+ // The following 2 fields are NULL if SuppressBackgroundThread is FALSE.
+ // Otherwise, they are functions which must be called appropriately to
+ // replace the background thread.
+ //
+ // These should be called on the application's main message loop - i.e.
+ // a message loop which is active for the lifetime of GDI+.
+ // "NotificationHook" should be called before starting the loop,
+ // and "NotificationUnhook" should be called after the loop ends.
+
+ NotificationHookProc NotificationHook;
+ NotificationUnhookProc NotificationUnhook;
+};
+
+// GDI+ initialization. Must be called before GDI+ API's are used.
+//
+// token - may not be NULL - accepts a token to be passed in the corresponding
+// GdiplusShutdown call.
+// input - may not be NULL
+// output - may be NULL only if input->SuppressBackgroundThread is FALSE.
+
+extern "C" Status WINAPI GdiplusStartup(
+ OUT ULONG_PTR *token,
+ const GdiplusStartupInput *input,
+ OUT GdiplusStartupOutput *output);
+
+// GDI+ termination. Must be called before GDI+ is unloaded. GDI+ API's may not
+// be called after this.
+
+extern "C" VOID WINAPI GdiplusShutdown(ULONG_PTR token);
+
+#endif
diff --git a/core/src/fxge/Microsoft SDK/include/sal.h b/core/src/fxge/Microsoft SDK/include/sal.h
index 136996974a..07234950cd 100644
--- a/core/src/fxge/Microsoft SDK/include/sal.h
+++ b/core/src/fxge/Microsoft SDK/include/sal.h
@@ -1,729 +1,729 @@
-/***
-*sal.h - markers for documenting the semantics of APIs
-*
-* Copyright (c) Microsoft Corporation. All rights reserved.
-*
-*Purpose:
-* sal.h provides a set of annotations to describe how a function uses its
-* parameters - the assumptions it makes about them, and the guarantees it makes
-* upon finishing.
-*
-* [Public]
-*
-****/
-
-/*
- -------------------------------------------------------------------------------
- Introduction
-
- sal.h provides a set of annotations to describe how a function uses its
- parameters - the assumptions it makes about them, and the guarantees it makes
- upon finishing.
-
- Annotations may be placed before either a function parameter's type or its return
- type, and describe the function's behavior regarding the parameter or return value.
- There are two classes of annotations: buffer annotations and advanced annotations.
- Buffer annotations describe how functions use their pointer parameters, and
- advanced annotations either describe complex/unusual buffer behavior, or provide
- additional information about a parameter that is not otherwise expressible.
-
- -------------------------------------------------------------------------------
- Buffer Annotations
-
- The most important annotations in sal.h provide a consistent way to annotate
- buffer parameters or return values for a function. Each of these annotations describes
- a single buffer (which could be a string, a fixed-length or variable-length array,
- or just a pointer) that the function interacts with: where it is, how large it is,
- how much is initialized, and what the function does with it.
-
- The appropriate macro for a given buffer can be constructed using the table below.
- Just pick the appropriate values from each category, and combine them together
- with a leading underscore. Some combinations of values do not make sense as buffer
- annotations. Only meaningful annotations can be added to your code; for a list of
- these, see the buffer annotation definitions section.
-
- Only a single buffer annotation should be used for each parameter.
-
- |------------|------------|---------|--------|----------|----------|---------------|
- | Level | Usage | Size | Output | NullTerm | Optional | Parameters |
- |------------|------------|---------|--------|----------|----------|---------------|
- | <> | <> | <> | <> | _z | <> | <> |
- | _deref | _in | _ecount | _full | _nz | _opt | (size) |
- | _deref_opt | _out | _bcount | _part | | | (size,length) |
- | | _inout | | | | | |
- | | | | | | | |
- |------------|------------|---------|--------|----------|----------|---------------|
-
- Level: Describes the buffer pointer's level of indirection from the parameter or
- return value 'p'.
-
- <> : p is the buffer pointer.
- _deref : *p is the buffer pointer. p must not be NULL.
- _deref_opt : *p may be the buffer pointer. p may be NULL, in which case the rest of
- the annotation is ignored.
-
- Usage: Describes how the function uses the buffer.
-
- <> : The buffer is not accessed. If used on the return value or with _deref, the
- function will provide the buffer, and it will be uninitialized at exit.
- Otherwise, the caller must provide the buffer. This should only be used
- for alloc and free functions.
- _in : The function will only read from the buffer. The caller must provide the
- buffer and initialize it. Cannot be used with _deref.
- _out : The function will only write to the buffer. If used on the return value or
- with _deref, the function will provide the buffer and initialize it.
- Otherwise, the caller must provide the buffer, and the function will
- initialize it.
- _inout : The function may freely read from and write to the buffer. The caller must
- provide the buffer and initialize it. If used with _deref, the buffer may
- be reallocated by the function.
-
- Size: Describes the total size of the buffer. This may be less than the space actually
- allocated for the buffer, in which case it describes the accessible amount.
-
- <> : No buffer size is given. If the type specifies the buffer size (such as
- with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is one
- element long. Must be used with _in, _out, or _inout.
- _ecount : The buffer size is an explicit element count.
- _bcount : The buffer size is an explicit byte count.
-
- Output: Describes how much of the buffer will be initialized by the function. For
- _inout buffers, this also describes how much is initialized at entry. Omit this
- category for _in buffers; they must be fully initialized by the caller.
-
- <> : The type specifies how much is initialized. For instance, a function initializing
- an LPWSTR must NULL-terminate the string.
- _full : The function initializes the entire buffer.
- _part : The function initializes part of the buffer, and explicitly indicates how much.
-
- NullTerm: States if the present of a '\0' marks the end of valid elements in the buffer.
- _z : A '\0' indicated the end of the buffer
- _nz : The buffer may not be null terminated and a '\0' does not indicate the end of the
- buffer.
- Optional: Describes if the buffer itself is optional.
-
- <> : The pointer to the buffer must not be NULL.
- _opt : The pointer to the buffer might be NULL. It will be checked before being dereferenced.
-
- Parameters: Gives explicit counts for the size and length of the buffer.
-
- <> : There is no explicit count. Use when neither _ecount nor _bcount is used.
- (size) : Only the buffer's total size is given. Use with _ecount or _bcount but not _part.
- (size,length) : The buffer's total size and initialized length are given. Use with _ecount_part
- and _bcount_part.
-
- -------------------------------------------------------------------------------
- Buffer Annotation Examples
-
- LWSTDAPI_(BOOL) StrToIntExA(
- LPCSTR pszString, -- No annotation required, const implies __in.
- DWORD dwFlags,
- __out int *piRet -- A pointer whose dereference will be filled in.
- );
-
- void MyPaintingFunction(
- __in HWND hwndControl, -- An initialized read-only parameter.
- __in_opt HDC hdcOptional, -- An initialized read-only parameter that might be NULL.
- __inout IPropertyStore *ppsStore -- An initialized parameter that may be freely used
- -- and modified.
- );
-
- LWSTDAPI_(BOOL) PathCompactPathExA(
- __out_ecount(cchMax) LPSTR pszOut, -- A string buffer with cch elements that will
- -- be NULL terminated on exit.
- LPCSTR pszSrc, -- No annotation required, const implies __in.
- UINT cchMax,
- DWORD dwFlags
- );
-
- HRESULT SHLocalAllocBytes(
- size_t cb,
- __deref_bcount(cb) T **ppv -- A pointer whose dereference will be set to an
- -- uninitialized buffer with cb bytes.
- );
-
- __inout_bcount_full(cb) : A buffer with cb elements that is fully initialized at
- entry and exit, and may be written to by this function.
-
- __out_ecount_part(count, *countOut) : A buffer with count elements that will be
- partially initialized by this function. The function indicates how much it
- initialized by setting *countOut.
-
- -------------------------------------------------------------------------------
- Advanced Annotations
-
- Advanced annotations describe behavior that is not expressible with the regular
- buffer macros. These may be used either to annotate buffer parameters that involve
- complex or conditional behavior, or to enrich existing annotations with additional
- information.
-
- __success(expr) f :
- <expr> indicates whether function f succeeded or not. If <expr> is true at exit,
- all the function's guarantees (as given by other annotations) must hold. If <expr>
- is false at exit, the caller should not expect any of the function's guarantees
- to hold. If not used, the function must always satisfy its guarantees. Added
- automatically to functions that indicate success in standard ways, such as by
- returning an HRESULT.
-
- __nullterminated p :
- Pointer p is a buffer that may be read or written up to and including the first
- NULL character or pointer. May be used on typedefs, which marks valid (properly
- initialized) instances of that type as being NULL-terminated.
-
- __nullnullterminated p :
- Pointer p is a buffer that may be read or written up to and including the first
- sequence of two NULL characters or pointers. May be used on typedefs, which marks
- valid instances of that type as being double-NULL terminated.
-
- __reserved v :
- Value v must be 0/NULL, reserved for future use.
-
- __checkReturn v :
- Return value v must not be ignored by callers of this function.
-
- __typefix(ctype) v :
- Value v should be treated as an instance of ctype, rather than its declared type.
-
- __override f :
- Specify C#-style 'override' behaviour for overriding virtual methods.
-
- __callback f :
- Function f can be used as a function pointer.
-
- __format_string p :
- Pointer p is a string that contains % markers in the style of printf.
-
- __blocksOn(resource) f :
- Function f blocks on the resource 'resource'.
-
- __fallthrough :
- Annotates switch statement labels where fall-through is desired, to distinguish
- from forgotten break statements.
-
- -------------------------------------------------------------------------------
- Advanced Annotation Examples
-
- __success(return == TRUE) LWSTDAPI_(BOOL)
- PathCanonicalizeA(__out_ecount(MAX_PATH) LPSTR pszBuf, LPCSTR pszPath) :
- pszBuf is only guaranteed to be NULL-terminated when TRUE is returned.
-
- typedef __nullterminated WCHAR* LPWSTR : Initialized LPWSTRs are NULL-terminated strings.
-
- __out_ecount(cch) __typefix(LPWSTR) void *psz : psz is a buffer parameter which will be
- a NULL-terminated WCHAR string at exit, and which initially contains cch WCHARs.
-
- -------------------------------------------------------------------------------
-*/
-
-#pragma once
-
-#define __specstrings
-
-#ifdef __cplusplus
-#ifndef __nothrow
-# define __nothrow __declspec(nothrow)
-#endif
-extern "C" {
-#else
-#ifndef __nothrow
-# define __nothrow
-#endif
-#endif /* #ifdef __cplusplus */
-
-/*
- -------------------------------------------------------------------------------
- Helper Macro Definitions
-
- These express behavior common to many of the high-level annotations.
- DO NOT USE THESE IN YOUR CODE.
- -------------------------------------------------------------------------------
-*/
-
-/*
-The helper annotations are only understood by the compiler version used by various
-defect detection tools. When the regular compiler is running, they are defined into
-nothing, and do not affect the compiled code.
-*/
-
-#if !defined(__midl) && defined(_PREFAST_)
-
- /*
- In the primitive __declspec("SAL_*") annotations "SAL" stands for Standard
- Annotation Language. These __declspec("SAL_*") annotations are the
- primitives the compiler understands and all high-level SpecString MACROs
- will decompose into these primivates.
- */
-
- #define SPECSTRINGIZE( x ) #x
-
- /*
- __null p
- __notnull p
- __maybenull p
-
- Annotates a pointer p. States that pointer p is null. Commonly used
- in the negated form __notnull or the possibly null form __maybenull.
- */
-
- #define __null __declspec("SAL_null")
- #define __notnull __declspec("SAL_notnull")
- #define __maybenull __declspec("SAL_maybenull")
-
- /*
- __readonly l
- __notreadonly l
- __mabyereadonly l
-
- Annotates a location l. States that location l is not modified after
- this point. If the annotation is placed on the precondition state of
- a function, the restriction only applies until the postcondition state
- of the function. __maybereadonly states that the annotated location
- may be modified, whereas __notreadonly states that a location must be
- modified.
- */
-
- #define __readonly __declspec("SAL_readonly")
- #define __notreadonly __declspec("SAL_notreadonly")
- #define __maybereadonly __declspec("SAL_maybereadonly")
-
- /*
- __valid v
- __notvalid v
- __maybevalid v
-
- Annotates any value v. States that the value satisfies all properties of
- valid values of its type. For example, for a string buffer, valid means
- that the buffer pointer is either NULL or points to a NULL-terminated string.
- */
-
- #define __valid __declspec("SAL_valid")
- #define __notvalid __declspec("SAL_notvalid")
- #define __maybevalid __declspec("SAL_maybevalid")
-
- /*
- __readableTo(extent) p
-
- Annotates a buffer pointer p. If the buffer can be read, extent describes
- how much of the buffer is readable. For a reader of the buffer, this is
- an explicit permission to read up to that amount, rather than a restriction to
- read only up to it.
- */
-
- #define __readableTo(extent) __declspec("SAL_readableTo("SPECSTRINGIZE(extent)")")
-
- /*
-
- __elem_readableTo(size)
-
- Annotates a buffer pointer p as being readable to size elements.
- */
-
- #define __elem_readableTo(size) __declspec("SAL_readableTo(elementCount("SPECSTRINGIZE(size)"))")
-
- /*
- __byte_readableTo(size)
-
- Annotates a buffer pointer p as being readable to size bytes.
- */
- #define __byte_readableTo(size) __declspec("SAL_readableTo(byteCount("SPECSTRINGIZE(size)"))")
-
- /*
- __writableTo(extent) p
-
- Annotates a buffer pointer p. If the buffer can be modified, extent
- describes how much of the buffer is writable (usually the allocation
- size). For a writer of the buffer, this is an explicit permission to
- write up to that amount, rather than a restriction to write only up to it.
- */
- #define __writableTo(size) __declspec("SAL_writableTo("SPECSTRINGIZE(size)")")
-
- /*
- __elem_writableTo(size)
-
- Annotates a buffer pointer p as being writable to size elements.
- */
- #define __elem_writableTo(size) __declspec("SAL_writableTo(elementCount("SPECSTRINGIZE(size)"))")
-
- /*
- __byte_writableTo(size)
-
- Annotates a buffer pointer p as being writable to size bytes.
- */
- #define __byte_writableTo(size) __declspec("SAL_writableTo(byteCount("SPECSTRINGIZE(size)"))")
-
- /*
- __deref p
-
- Annotates a pointer p. The next annotation applies one dereference down
- in the type. If readableTo(p, size) then the next annotation applies to
- all elements *(p+i) for which i satisfies the size. If p is a pointer
- to a struct, the next annotation applies to all fields of the struct.
- */
- #define __deref __declspec("SAL_deref")
-
- /*
- __pre __next_annotation
-
- The next annotation applies in the precondition state
- */
- #define __pre __declspec("SAL_pre")
-
- /*
- __post __next_annotation
-
- The next annotation applies in the postcondition state
- */
- #define __post __declspec("SAL_post")
-
- /*
- __precond(<expr>)
-
- When <expr> is true, the next annotation applies in the precondition state
- (currently not enabled)
- */
- #define __precond(expr) __pre
-
- /*
- __postcond(<expr>)
-
- When <expr> is true, the next annotation applies in the postcondition state
- (currently not enabled)
- */
- #define __postcond(expr) __post
-
- /*
- __exceptthat
-
- Given a set of annotations Q containing __exceptthat maybeP, the effect of
- the except clause is to erase any P or notP annotations (explicit or
- implied) within Q at the same level of dereferencing that the except
- clause appears, and to replace it with maybeP.
-
- Example 1: __valid __exceptthat __maybenull on a pointer p means that the
- pointer may be null, and is otherwise valid, thus overriding
- the implicit notnull annotation implied by __valid on
- pointers.
-
- Example 2: __valid __deref __exceptthat __maybenull on an int **p means
- that p is not null (implied by valid), but the elements
- pointed to by p could be null, and are otherwise valid.
- */
- #define __exceptthat __declspec("SAL_except")
- #define __execeptthat __exceptthat
-
- /*
- _refparam
-
- Added to all out parameter macros to indicate that they are all reference
- parameters.
- */
- #define __refparam __deref __notreadonly
-
- /*
- __inner_*
-
- Helper macros that directly correspond to certain high-level annotations.
-
- */
-
- /*
- Macros to classify the entrypoints and indicate their category.
-
- Pre-defined control point categories include: RPC, LPC, DeviceDriver, UserToKernel, ISAPI, COM.
-
- */
- #define __inner_control_entrypoint(category) __declspec("SAL_entrypoint(controlEntry, "SPECSTRINGIZE(category)")")
-
- /*
- Pre-defined data entry point categories include: Registry, File, Network.
- */
- #define __inner_data_entrypoint(category) __declspec("SAL_entrypoint(dataEntry, "SPECSTRINGIZE(category)")")
-
- #define __inner_success(expr) __declspec("SAL_success("SPECSTRINGIZE(expr)")")
- #define __inner_checkReturn __declspec("SAL_checkReturn")
- #define __inner_typefix(ctype) __declspec("SAL_typefix("SPECSTRINGIZE(ctype)")")
- #define __inner_override __declspec("__override")
- #define __inner_callback __declspec("__callback")
- #define __inner_blocksOn(resource) __declspec("SAL_blocksOn("SPECSTRINGIZE(resource)")")
- #define __inner_fallthrough_dec __inline __nothrow void __FallThrough() {}
- #define __inner_fallthrough __FallThrough();
-
-#else
- #define __null
- #define __notnull
- #define __maybenull
- #define __readonly
- #define __notreadonly
- #define __maybereadonly
- #define __valid
- #define __notvalid
- #define __maybevalid
- #define __readableTo(extent)
- #define __elem_readableTo(size)
- #define __byte_readableTo(size)
- #define __writableTo(size)
- #define __elem_writableTo(size)
- #define __byte_writableTo(size)
- #define __deref
- #define __pre
- #define __post
- #define __precond(expr)
- #define __postcond(expr)
- #define __exceptthat
- #define __execeptthat
- #define __inner_success(expr)
- #define __inner_checkReturn
- #define __inner_typefix(ctype)
- #define __inner_override
- #define __inner_callback
- #define __inner_blocksOn(resource)
- #define __inner_fallthrough_dec
- #define __inner_fallthrough
- #define __refparam
- #define __inner_control_entrypoint(category)
- #define __inner_data_entrypoint(category)
-#endif /* #if !defined(__midl) && defined(_PREFAST_) */
-
-/*
--------------------------------------------------------------------------------
-Buffer Annotation Definitions
-
-Any of these may be used to directly annotate functions, but only one should
-be used for each parameter. To determine which annotation to use for a given
-buffer, use the table in the buffer annotations section.
--------------------------------------------------------------------------------
-*/
-
-#define __ecount(size) __notnull __elem_writableTo(size)
-#define __bcount(size) __notnull __byte_writableTo(size)
-#define __in __pre __valid __pre __deref __readonly
-#define __in_ecount(size) __in __pre __elem_readableTo(size)
-#define __in_bcount(size) __in __pre __byte_readableTo(size)
-#define __in_z __in __pre __nullterminated
-#define __in_ecount_z(size) __in_ecount(size) __pre __nullterminated
-#define __in_bcount_z(size) __in_bcount(size) __pre __nullterminated
-#define __in_nz __in
-#define __in_ecount_nz(size) __in_ecount(size)
-#define __in_bcount_nz(size) __in_bcount(size)
-#define __out __ecount(1) __post __valid __refparam
-#define __out_ecount(size) __ecount(size) __post __valid __refparam
-#define __out_bcount(size) __bcount(size) __post __valid __refparam
-#define __out_ecount_part(size,length) __out_ecount(size) __post __elem_readableTo(length)
-#define __out_bcount_part(size,length) __out_bcount(size) __post __byte_readableTo(length)
-#define __out_ecount_full(size) __out_ecount_part(size,size)
-#define __out_bcount_full(size) __out_bcount_part(size,size)
-#define __out_z __post __valid __refparam __post __nullterminated
-#define __out_z_opt __post __valid __refparam __post __nullterminated __exceptthat __maybenull
-#define __out_ecount_z(size) __ecount(size) __post __valid __refparam __post __nullterminated
-#define __out_bcount_z(size) __bcount(size) __post __valid __refparam __post __nullterminated
-#define __out_ecount_part_z(size,length) __out_ecount_part(size,length) __post __nullterminated
-#define __out_bcount_part_z(size,length) __out_bcount_part(size,length) __post __nullterminated
-#define __out_ecount_full_z(size) __out_ecount_full(size) __post __nullterminated
-#define __out_bcount_full_z(size) __out_bcount_full(size) __post __nullterminated
-#define __out_nz __post __valid __refparam __post
-#define __out_nz_opt __post __valid __refparam __post __exceptthat __maybenull
-#define __out_ecount_nz(size) __ecount(size) __post __valid __refparam
-#define __out_bcount_nz(size) __bcount(size) __post __valid __refparam
-#define __inout __pre __valid __post __valid __refparam
-#define __inout_ecount(size) __out_ecount(size) __pre __valid
-#define __inout_bcount(size) __out_bcount(size) __pre __valid
-#define __inout_ecount_part(size,length) __out_ecount_part(size,length) __pre __valid __pre __elem_readableTo(length)
-#define __inout_bcount_part(size,length) __out_bcount_part(size,length) __pre __valid __pre __byte_readableTo(length)
-#define __inout_ecount_full(size) __inout_ecount_part(size,size)
-#define __inout_bcount_full(size) __inout_bcount_part(size,size)
-#define __inout_z __inout __pre __nullterminated __post __nullterminated
-#define __inout_ecount_z(size) __inout_ecount(size) __pre __nullterminated __post __nullterminated
-#define __inout_bcount_z(size) __inout_bcount(size) __pre __nullterminated __post __nullterminated
-#define __inout_nz __inout
-#define __inout_ecount_nz(size) __inout_ecount(size)
-#define __inout_bcount_nz(size) __inout_bcount(size)
-#define __ecount_opt(size) __ecount(size) __exceptthat __maybenull
-#define __bcount_opt(size) __bcount(size) __exceptthat __maybenull
-#define __in_opt __in __exceptthat __maybenull
-#define __in_ecount_opt(size) __in_ecount(size) __exceptthat __maybenull
-#define __in_bcount_opt(size) __in_bcount(size) __exceptthat __maybenull
-#define __in_z_opt __in_opt __pre __nullterminated
-#define __in_ecount_z_opt(size) __in_ecount_opt(size) __pre __nullterminated
-#define __in_bcount_z_opt(size) __in_bcount_opt(size) __pre __nullterminated
-#define __in_nz_opt __in_opt
-#define __in_ecount_nz_opt(size) __in_ecount_opt(size)
-#define __in_bcount_nz_opt(size) __in_bcount_opt(size)
-#define __out_opt __out __exceptthat __maybenull
-#define __out_ecount_opt(size) __out_ecount(size) __exceptthat __maybenull
-#define __out_bcount_opt(size) __out_bcount(size) __exceptthat __maybenull
-#define __out_ecount_part_opt(size,length) __out_ecount_part(size,length) __exceptthat __maybenull
-#define __out_bcount_part_opt(size,length) __out_bcount_part(size,length) __exceptthat __maybenull
-#define __out_ecount_full_opt(size) __out_ecount_full(size) __exceptthat __maybenull
-#define __out_bcount_full_opt(size) __out_bcount_full(size) __exceptthat __maybenull
-#define __out_ecount_z_opt(size) __out_ecount_opt(size) __post __nullterminated
-#define __out_bcount_z_opt(size) __out_bcount_opt(size) __post __nullterminated
-#define __out_ecount_part_z_opt(size,length) __out_ecount_part_opt(size,length) __post __nullterminated
-#define __out_bcount_part_z_opt(size,length) __out_bcount_part_opt(size,length) __post __nullterminated
-#define __out_ecount_full_z_opt(size) __out_ecount_full_opt(size) __post __nullterminated
-#define __out_bcount_full_z_opt(size) __out_bcount_full_opt(size) __post __nullterminated
-#define __out_ecount_nz_opt(size) __out_ecount_opt(size) __post __nullterminated
-#define __out_bcount_nz_opt(size) __out_bcount_opt(size) __post __nullterminated
-#define __inout_opt __inout __exceptthat __maybenull
-#define __inout_ecount_opt(size) __inout_ecount(size) __exceptthat __maybenull
-#define __inout_bcount_opt(size) __inout_bcount(size) __exceptthat __maybenull
-#define __inout_ecount_part_opt(size,length) __inout_ecount_part(size,length) __exceptthat __maybenull
-#define __inout_bcount_part_opt(size,length) __inout_bcount_part(size,length) __exceptthat __maybenull
-#define __inout_ecount_full_opt(size) __inout_ecount_full(size) __exceptthat __maybenull
-#define __inout_bcount_full_opt(size) __inout_bcount_full(size) __exceptthat __maybenull
-#define __inout_z_opt __inout_opt __pre __nullterminated __post __nullterminated
-#define __inout_ecount_z_opt(size) __inout_ecount_opt(size) __pre __nullterminated __post __nullterminated
-#define __inout_ecount_z_opt(size) __inout_ecount_opt(size) __pre __nullterminated __post __nullterminated
-#define __inout_bcount_z_opt(size) __inout_bcount_opt(size)
-#define __inout_nz_opt __inout_opt
-#define __inout_ecount_nz_opt(size) __inout_ecount_opt(size)
-#define __inout_bcount_nz_opt(size) __inout_bcount_opt(size)
-#define __deref_ecount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __elem_writableTo(size)
-#define __deref_bcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __byte_writableTo(size)
-#define __deref_out __deref_ecount(1) __post __deref __valid __refparam
-#define __deref_out_ecount(size) __deref_ecount(size) __post __deref __valid __refparam
-#define __deref_out_bcount(size) __deref_bcount(size) __post __deref __valid __refparam
-#define __deref_out_ecount_part(size,length) __deref_out_ecount(size) __post __deref __elem_readableTo(length)
-#define __deref_out_bcount_part(size,length) __deref_out_bcount(size) __post __deref __byte_readableTo(length)
-#define __deref_out_ecount_full(size) __deref_out_ecount_part(size,size)
-#define __deref_out_bcount_full(size) __deref_out_bcount_part(size,size)
-#define __deref_out_z __post __deref __valid __refparam __post __deref __nullterminated
-#define __deref_out_ecount_z(size) __deref_out_ecount(size) __post __deref __nullterminated
-#define __deref_out_bcount_z(size) __deref_out_ecount(size) __post __deref __nullterminated
-#define __deref_out_nz __deref_out
-#define __deref_out_ecount_nz(size) __deref_out_ecount(size)
-#define __deref_out_bcount_nz(size) __deref_out_ecount(size)
-#define __deref_inout __notnull __elem_readableTo(1) __pre __deref __valid __post __deref __valid __refparam
-#define __deref_inout_z __deref_inout __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_inout_ecount(size) __deref_inout __pre __deref __elem_writableTo(size) __post __deref __elem_writableTo(size)
-#define __deref_inout_bcount(size) __deref_inout __pre __deref __byte_writableTo(size) __post __deref __byte_writableTo(size)
-#define __deref_inout_ecount_part(size,length) __deref_inout_ecount(size) __pre __deref __elem_readableTo(length) __post __deref __elem_readableTo(length)
-#define __deref_inout_bcount_part(size,length) __deref_inout_bcount(size) __pre __deref __byte_readableTo(length) __post __deref __byte_readableTo(length)
-#define __deref_inout_ecount_full(size) __deref_inout_ecount_part(size,size)
-#define __deref_inout_bcount_full(size) __deref_inout_bcount_part(size,size)
-#define __deref_inout_z __deref_inout __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_inout_ecount_z(size) __deref_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_inout_bcount_z(size) __deref_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_inout_nz __deref_inout
-#define __deref_inout_ecount_nz(size) __deref_inout_ecount(size)
-#define __deref_inout_bcount_nz(size) __deref_inout_ecount(size)
-#define __deref_ecount_opt(size) __deref_ecount(size) __post __deref __exceptthat __maybenull
-#define __deref_bcount_opt(size) __deref_bcount(size) __post __deref __exceptthat __maybenull
-#define __deref_out_opt __deref_out __post __deref __exceptthat __maybenull
-#define __deref_out_ecount_opt(size) __deref_out_ecount(size) __post __deref __exceptthat __maybenull
-#define __deref_out_bcount_opt(size) __deref_out_bcount(size) __post __deref __exceptthat __maybenull
-#define __deref_out_ecount_part_opt(size,length) __deref_out_ecount_part(size,length) __post __deref __exceptthat __maybenull
-#define __deref_out_bcount_part_opt(size,length) __deref_out_bcount_part(size,length) __post __deref __exceptthat __maybenull
-#define __deref_out_ecount_full_opt(size) __deref_out_ecount_full(size) __post __deref __exceptthat __maybenull
-#define __deref_out_bcount_full_opt(size) __deref_out_bcount_full(size) __post __deref __exceptthat __maybenull
-#define __deref_out_z_opt __post __deref __valid __refparam __execeptthat __maybenull __post __deref __nullterminated
-#define __deref_out_ecount_z_opt(size) __deref_out_ecount_opt(size) __post __deref __nullterminated
-#define __deref_out_bcount_z_opt(size) __deref_out_bcount_opt(size) __post __deref __nullterminated
-#define __deref_out_nz_opt __deref_out_opt
-#define __deref_out_ecount_nz_opt(size) __deref_out_ecount_opt(size)
-#define __deref_out_bcount_nz_opt(size) __deref_out_bcount_opt(size)
-#define __deref_inout_opt __deref_inout __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#define __deref_inout_ecount_opt(size) __deref_inout_ecount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#define __deref_inout_bcount_opt(size) __deref_inout_bcount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#define __deref_inout_ecount_part_opt(size,length) __deref_inout_ecount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#define __deref_inout_bcount_part_opt(size,length) __deref_inout_bcount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#define __deref_inout_ecount_full_opt(size) __deref_inout_ecount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#define __deref_inout_bcount_full_opt(size) __deref_inout_bcount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#define __deref_inout_z_opt __deref_inout_opt __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_inout_ecount_z_opt(size) __deref_inout_ecount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_inout_bcount_z_opt(size) __deref_inout_bcount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_inout_nz_opt __deref_inout_opt
-#define __deref_inout_ecount_nz_opt(size) __deref_inout_ecount_opt(size)
-#define __deref_inout_bcount_nz_opt(size) __deref_inout_bcount_opt(size)
-#define __deref_opt_ecount(size) __deref_ecount(size) __exceptthat __maybenull
-#define __deref_opt_bcount(size) __deref_bcount(size) __exceptthat __maybenull
-#define __deref_opt_out __deref_out __exceptthat __maybenull
-#define __deref_opt_out_z __deref_opt_out __post __deref __nullterminated
-#define __deref_opt_out_ecount(size) __deref_out_ecount(size) __exceptthat __maybenull
-#define __deref_opt_out_bcount(size) __deref_out_bcount(size) __exceptthat __maybenull
-#define __deref_opt_out_ecount_part(size,length) __deref_out_ecount_part(size,length) __exceptthat __maybenull
-#define __deref_opt_out_bcount_part(size,length) __deref_out_bcount_part(size,length) __exceptthat __maybenull
-#define __deref_opt_out_ecount_full(size) __deref_out_ecount_full(size) __exceptthat __maybenull
-#define __deref_opt_out_bcount_full(size) __deref_out_bcount_full(size) __exceptthat __maybenull
-#define __deref_opt_inout __deref_inout __exceptthat __maybenull
-#define __deref_opt_inout_ecount(size) __deref_inout_ecount(size) __exceptthat __maybenull
-#define __deref_opt_inout_bcount(size) __deref_inout_bcount(size) __exceptthat __maybenull
-#define __deref_opt_inout_ecount_part(size,length) __deref_inout_ecount_part(size,length) __exceptthat __maybenull
-#define __deref_opt_inout_bcount_part(size,length) __deref_inout_bcount_part(size,length) __exceptthat __maybenull
-#define __deref_opt_inout_ecount_full(size) __deref_inout_ecount_full(size) __exceptthat __maybenull
-#define __deref_opt_inout_bcount_full(size) __deref_inout_bcount_full(size) __exceptthat __maybenull
-#define __deref_opt_inout_z __deref_opt_inout __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_opt_inout_ecount_z(size) __deref_opt_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_opt_inout_bcount_z(size) __deref_opt_inout_bcount(size) __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_opt_inout_nz __deref_opt_inout
-#define __deref_opt_inout_ecount_nz(size) __deref_opt_inout_ecount(size)
-#define __deref_opt_inout_bcount_nz(size) __deref_opt_inout_bcount(size)
-#define __deref_opt_ecount_opt(size) __deref_ecount_opt(size) __exceptthat __maybenull
-#define __deref_opt_bcount_opt(size) __deref_bcount_opt(size) __exceptthat __maybenull
-#define __deref_opt_out_opt __deref_out_opt __exceptthat __maybenull
-#define __deref_opt_out_ecount_opt(size) __deref_out_ecount_opt(size) __exceptthat __maybenull
-#define __deref_opt_out_bcount_opt(size) __deref_out_bcount_opt(size) __exceptthat __maybenull
-#define __deref_opt_out_ecount_part_opt(size,length) __deref_out_ecount_part_opt(size,length) __exceptthat __maybenull
-#define __deref_opt_out_bcount_part_opt(size,length) __deref_out_bcount_part_opt(size,length) __exceptthat __maybenull
-#define __deref_opt_out_ecount_full_opt(size) __deref_out_ecount_full_opt(size) __exceptthat __maybenull
-#define __deref_opt_out_bcount_full_opt(size) __deref_out_bcount_full_opt(size) __exceptthat __maybenull
-#define __deref_opt_out_z_opt __post __deref __valid __refparam __exceptthat __maybenull __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull __post __deref __nullterminated
-#define __deref_opt_out_ecount_z_opt(size) __deref_opt_out_ecount_opt(size) __post __deref __nullterminated
-#define __deref_opt_out_bcount_z_opt(size) __deref_opt_out_bcount_opt(size) __post __deref __nullterminated
-#define __deref_opt_out_nz_opt __deref_opt_out_opt
-#define __deref_opt_out_ecount_nz_opt(size) __deref_opt_out_ecount_opt(size)
-#define __deref_opt_out_bcount_nz_opt(size) __deref_opt_out_bcount_opt(size)
-#define __deref_opt_inout_opt __deref_inout_opt __exceptthat __maybenull
-#define __deref_opt_inout_ecount_opt(size) __deref_inout_ecount_opt(size) __exceptthat __maybenull
-#define __deref_opt_inout_bcount_opt(size) __deref_inout_bcount_opt(size) __exceptthat __maybenull
-#define __deref_opt_inout_ecount_part_opt(size,length) __deref_inout_ecount_part_opt(size,length) __exceptthat __maybenull
-#define __deref_opt_inout_bcount_part_opt(size,length) __deref_inout_bcount_part_opt(size,length) __exceptthat __maybenull
-#define __deref_opt_inout_ecount_full_opt(size) __deref_inout_ecount_full_opt(size) __exceptthat __maybenull
-#define __deref_opt_inout_bcount_full_opt(size) __deref_inout_bcount_full_opt(size) __exceptthat __maybenull
-#define __deref_opt_inout_z_opt __deref_opt_inout_opt __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_opt_inout_ecount_z_opt(size) __deref_opt_inout_ecount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_opt_inout_bcount_z_opt(size) __deref_opt_inout_bcount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
-#define __deref_opt_inout_nz_opt __deref_opt_inout_opt
-#define __deref_opt_inout_ecount_nz_opt(size) __deref_opt_inout_ecount_opt(size)
-#define __deref_opt_inout_bcount_nz_opt(size) __deref_opt_inout_bcount_opt(size)
-
-/*
--------------------------------------------------------------------------------
-Advanced Annotation Definitions
-
-Any of these may be used to directly annotate functions, and may be used in
-combination with each other or with regular buffer macros. For an explanation
-of each annotation, see the advanced annotations section.
--------------------------------------------------------------------------------
-*/
-
-#define __success(expr) __inner_success(expr)
-#define __nullterminated __readableTo(sentinel(0))
-#define __nullnullterminated
-#define __reserved __pre __null
-#define __checkReturn __inner_checkReturn
-#define __typefix(ctype) __inner_typefix(ctype)
-#define __override __inner_override
-#define __callback __inner_callback
-#define __format_string
-#define __blocksOn(resource) __inner_blocksOn(resource)
-#define __control_entrypoint(category) __inner_control_entrypoint(category)
-#define __data_entrypoint(category) __inner_data_entrypoint(category)
-
-#ifndef __fallthrough
- __inner_fallthrough_dec
- #define __fallthrough __inner_fallthrough
-#endif
-
-#ifndef __analysis_assume
-#ifdef _PREFAST_
-#define __analysis_assume(expr) __assume(expr)
-#else
-#define __analysis_assume(expr)
-#endif
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-
+/***
+*sal.h - markers for documenting the semantics of APIs
+*
+* Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*Purpose:
+* sal.h provides a set of annotations to describe how a function uses its
+* parameters - the assumptions it makes about them, and the guarantees it makes
+* upon finishing.
+*
+* [Public]
+*
+****/
+
+/*
+ -------------------------------------------------------------------------------
+ Introduction
+
+ sal.h provides a set of annotations to describe how a function uses its
+ parameters - the assumptions it makes about them, and the guarantees it makes
+ upon finishing.
+
+ Annotations may be placed before either a function parameter's type or its return
+ type, and describe the function's behavior regarding the parameter or return value.
+ There are two classes of annotations: buffer annotations and advanced annotations.
+ Buffer annotations describe how functions use their pointer parameters, and
+ advanced annotations either describe complex/unusual buffer behavior, or provide
+ additional information about a parameter that is not otherwise expressible.
+
+ -------------------------------------------------------------------------------
+ Buffer Annotations
+
+ The most important annotations in sal.h provide a consistent way to annotate
+ buffer parameters or return values for a function. Each of these annotations describes
+ a single buffer (which could be a string, a fixed-length or variable-length array,
+ or just a pointer) that the function interacts with: where it is, how large it is,
+ how much is initialized, and what the function does with it.
+
+ The appropriate macro for a given buffer can be constructed using the table below.
+ Just pick the appropriate values from each category, and combine them together
+ with a leading underscore. Some combinations of values do not make sense as buffer
+ annotations. Only meaningful annotations can be added to your code; for a list of
+ these, see the buffer annotation definitions section.
+
+ Only a single buffer annotation should be used for each parameter.
+
+ |------------|------------|---------|--------|----------|----------|---------------|
+ | Level | Usage | Size | Output | NullTerm | Optional | Parameters |
+ |------------|------------|---------|--------|----------|----------|---------------|
+ | <> | <> | <> | <> | _z | <> | <> |
+ | _deref | _in | _ecount | _full | _nz | _opt | (size) |
+ | _deref_opt | _out | _bcount | _part | | | (size,length) |
+ | | _inout | | | | | |
+ | | | | | | | |
+ |------------|------------|---------|--------|----------|----------|---------------|
+
+ Level: Describes the buffer pointer's level of indirection from the parameter or
+ return value 'p'.
+
+ <> : p is the buffer pointer.
+ _deref : *p is the buffer pointer. p must not be NULL.
+ _deref_opt : *p may be the buffer pointer. p may be NULL, in which case the rest of
+ the annotation is ignored.
+
+ Usage: Describes how the function uses the buffer.
+
+ <> : The buffer is not accessed. If used on the return value or with _deref, the
+ function will provide the buffer, and it will be uninitialized at exit.
+ Otherwise, the caller must provide the buffer. This should only be used
+ for alloc and free functions.
+ _in : The function will only read from the buffer. The caller must provide the
+ buffer and initialize it. Cannot be used with _deref.
+ _out : The function will only write to the buffer. If used on the return value or
+ with _deref, the function will provide the buffer and initialize it.
+ Otherwise, the caller must provide the buffer, and the function will
+ initialize it.
+ _inout : The function may freely read from and write to the buffer. The caller must
+ provide the buffer and initialize it. If used with _deref, the buffer may
+ be reallocated by the function.
+
+ Size: Describes the total size of the buffer. This may be less than the space actually
+ allocated for the buffer, in which case it describes the accessible amount.
+
+ <> : No buffer size is given. If the type specifies the buffer size (such as
+ with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is one
+ element long. Must be used with _in, _out, or _inout.
+ _ecount : The buffer size is an explicit element count.
+ _bcount : The buffer size is an explicit byte count.
+
+ Output: Describes how much of the buffer will be initialized by the function. For
+ _inout buffers, this also describes how much is initialized at entry. Omit this
+ category for _in buffers; they must be fully initialized by the caller.
+
+ <> : The type specifies how much is initialized. For instance, a function initializing
+ an LPWSTR must NULL-terminate the string.
+ _full : The function initializes the entire buffer.
+ _part : The function initializes part of the buffer, and explicitly indicates how much.
+
+ NullTerm: States if the present of a '\0' marks the end of valid elements in the buffer.
+ _z : A '\0' indicated the end of the buffer
+ _nz : The buffer may not be null terminated and a '\0' does not indicate the end of the
+ buffer.
+ Optional: Describes if the buffer itself is optional.
+
+ <> : The pointer to the buffer must not be NULL.
+ _opt : The pointer to the buffer might be NULL. It will be checked before being dereferenced.
+
+ Parameters: Gives explicit counts for the size and length of the buffer.
+
+ <> : There is no explicit count. Use when neither _ecount nor _bcount is used.
+ (size) : Only the buffer's total size is given. Use with _ecount or _bcount but not _part.
+ (size,length) : The buffer's total size and initialized length are given. Use with _ecount_part
+ and _bcount_part.
+
+ -------------------------------------------------------------------------------
+ Buffer Annotation Examples
+
+ LWSTDAPI_(BOOL) StrToIntExA(
+ LPCSTR pszString, -- No annotation required, const implies __in.
+ DWORD dwFlags,
+ __out int *piRet -- A pointer whose dereference will be filled in.
+ );
+
+ void MyPaintingFunction(
+ __in HWND hwndControl, -- An initialized read-only parameter.
+ __in_opt HDC hdcOptional, -- An initialized read-only parameter that might be NULL.
+ __inout IPropertyStore *ppsStore -- An initialized parameter that may be freely used
+ -- and modified.
+ );
+
+ LWSTDAPI_(BOOL) PathCompactPathExA(
+ __out_ecount(cchMax) LPSTR pszOut, -- A string buffer with cch elements that will
+ -- be NULL terminated on exit.
+ LPCSTR pszSrc, -- No annotation required, const implies __in.
+ UINT cchMax,
+ DWORD dwFlags
+ );
+
+ HRESULT SHLocalAllocBytes(
+ size_t cb,
+ __deref_bcount(cb) T **ppv -- A pointer whose dereference will be set to an
+ -- uninitialized buffer with cb bytes.
+ );
+
+ __inout_bcount_full(cb) : A buffer with cb elements that is fully initialized at
+ entry and exit, and may be written to by this function.
+
+ __out_ecount_part(count, *countOut) : A buffer with count elements that will be
+ partially initialized by this function. The function indicates how much it
+ initialized by setting *countOut.
+
+ -------------------------------------------------------------------------------
+ Advanced Annotations
+
+ Advanced annotations describe behavior that is not expressible with the regular
+ buffer macros. These may be used either to annotate buffer parameters that involve
+ complex or conditional behavior, or to enrich existing annotations with additional
+ information.
+
+ __success(expr) f :
+ <expr> indicates whether function f succeeded or not. If <expr> is true at exit,
+ all the function's guarantees (as given by other annotations) must hold. If <expr>
+ is false at exit, the caller should not expect any of the function's guarantees
+ to hold. If not used, the function must always satisfy its guarantees. Added
+ automatically to functions that indicate success in standard ways, such as by
+ returning an HRESULT.
+
+ __nullterminated p :
+ Pointer p is a buffer that may be read or written up to and including the first
+ NULL character or pointer. May be used on typedefs, which marks valid (properly
+ initialized) instances of that type as being NULL-terminated.
+
+ __nullnullterminated p :
+ Pointer p is a buffer that may be read or written up to and including the first
+ sequence of two NULL characters or pointers. May be used on typedefs, which marks
+ valid instances of that type as being double-NULL terminated.
+
+ __reserved v :
+ Value v must be 0/NULL, reserved for future use.
+
+ __checkReturn v :
+ Return value v must not be ignored by callers of this function.
+
+ __typefix(ctype) v :
+ Value v should be treated as an instance of ctype, rather than its declared type.
+
+ __override f :
+ Specify C#-style 'override' behaviour for overriding virtual methods.
+
+ __callback f :
+ Function f can be used as a function pointer.
+
+ __format_string p :
+ Pointer p is a string that contains % markers in the style of printf.
+
+ __blocksOn(resource) f :
+ Function f blocks on the resource 'resource'.
+
+ __fallthrough :
+ Annotates switch statement labels where fall-through is desired, to distinguish
+ from forgotten break statements.
+
+ -------------------------------------------------------------------------------
+ Advanced Annotation Examples
+
+ __success(return == TRUE) LWSTDAPI_(BOOL)
+ PathCanonicalizeA(__out_ecount(MAX_PATH) LPSTR pszBuf, LPCSTR pszPath) :
+ pszBuf is only guaranteed to be NULL-terminated when TRUE is returned.
+
+ typedef __nullterminated WCHAR* LPWSTR : Initialized LPWSTRs are NULL-terminated strings.
+
+ __out_ecount(cch) __typefix(LPWSTR) void *psz : psz is a buffer parameter which will be
+ a NULL-terminated WCHAR string at exit, and which initially contains cch WCHARs.
+
+ -------------------------------------------------------------------------------
+*/
+
+#pragma once
+
+#define __specstrings
+
+#ifdef __cplusplus
+#ifndef __nothrow
+# define __nothrow __declspec(nothrow)
+#endif
+extern "C" {
+#else
+#ifndef __nothrow
+# define __nothrow
+#endif
+#endif /* #ifdef __cplusplus */
+
+/*
+ -------------------------------------------------------------------------------
+ Helper Macro Definitions
+
+ These express behavior common to many of the high-level annotations.
+ DO NOT USE THESE IN YOUR CODE.
+ -------------------------------------------------------------------------------
+*/
+
+/*
+The helper annotations are only understood by the compiler version used by various
+defect detection tools. When the regular compiler is running, they are defined into
+nothing, and do not affect the compiled code.
+*/
+
+#if !defined(__midl) && defined(_PREFAST_)
+
+ /*
+ In the primitive __declspec("SAL_*") annotations "SAL" stands for Standard
+ Annotation Language. These __declspec("SAL_*") annotations are the
+ primitives the compiler understands and all high-level SpecString MACROs
+ will decompose into these primivates.
+ */
+
+ #define SPECSTRINGIZE( x ) #x
+
+ /*
+ __null p
+ __notnull p
+ __maybenull p
+
+ Annotates a pointer p. States that pointer p is null. Commonly used
+ in the negated form __notnull or the possibly null form __maybenull.
+ */
+
+ #define __null __declspec("SAL_null")
+ #define __notnull __declspec("SAL_notnull")
+ #define __maybenull __declspec("SAL_maybenull")
+
+ /*
+ __readonly l
+ __notreadonly l
+ __mabyereadonly l
+
+ Annotates a location l. States that location l is not modified after
+ this point. If the annotation is placed on the precondition state of
+ a function, the restriction only applies until the postcondition state
+ of the function. __maybereadonly states that the annotated location
+ may be modified, whereas __notreadonly states that a location must be
+ modified.
+ */
+
+ #define __readonly __declspec("SAL_readonly")
+ #define __notreadonly __declspec("SAL_notreadonly")
+ #define __maybereadonly __declspec("SAL_maybereadonly")
+
+ /*
+ __valid v
+ __notvalid v
+ __maybevalid v
+
+ Annotates any value v. States that the value satisfies all properties of
+ valid values of its type. For example, for a string buffer, valid means
+ that the buffer pointer is either NULL or points to a NULL-terminated string.
+ */
+
+ #define __valid __declspec("SAL_valid")
+ #define __notvalid __declspec("SAL_notvalid")
+ #define __maybevalid __declspec("SAL_maybevalid")
+
+ /*
+ __readableTo(extent) p
+
+ Annotates a buffer pointer p. If the buffer can be read, extent describes
+ how much of the buffer is readable. For a reader of the buffer, this is
+ an explicit permission to read up to that amount, rather than a restriction to
+ read only up to it.
+ */
+
+ #define __readableTo(extent) __declspec("SAL_readableTo("SPECSTRINGIZE(extent)")")
+
+ /*
+
+ __elem_readableTo(size)
+
+ Annotates a buffer pointer p as being readable to size elements.
+ */
+
+ #define __elem_readableTo(size) __declspec("SAL_readableTo(elementCount("SPECSTRINGIZE(size)"))")
+
+ /*
+ __byte_readableTo(size)
+
+ Annotates a buffer pointer p as being readable to size bytes.
+ */
+ #define __byte_readableTo(size) __declspec("SAL_readableTo(byteCount("SPECSTRINGIZE(size)"))")
+
+ /*
+ __writableTo(extent) p
+
+ Annotates a buffer pointer p. If the buffer can be modified, extent
+ describes how much of the buffer is writable (usually the allocation
+ size). For a writer of the buffer, this is an explicit permission to
+ write up to that amount, rather than a restriction to write only up to it.
+ */
+ #define __writableTo(size) __declspec("SAL_writableTo("SPECSTRINGIZE(size)")")
+
+ /*
+ __elem_writableTo(size)
+
+ Annotates a buffer pointer p as being writable to size elements.
+ */
+ #define __elem_writableTo(size) __declspec("SAL_writableTo(elementCount("SPECSTRINGIZE(size)"))")
+
+ /*
+ __byte_writableTo(size)
+
+ Annotates a buffer pointer p as being writable to size bytes.
+ */
+ #define __byte_writableTo(size) __declspec("SAL_writableTo(byteCount("SPECSTRINGIZE(size)"))")
+
+ /*
+ __deref p
+
+ Annotates a pointer p. The next annotation applies one dereference down
+ in the type. If readableTo(p, size) then the next annotation applies to
+ all elements *(p+i) for which i satisfies the size. If p is a pointer
+ to a struct, the next annotation applies to all fields of the struct.
+ */
+ #define __deref __declspec("SAL_deref")
+
+ /*
+ __pre __next_annotation
+
+ The next annotation applies in the precondition state
+ */
+ #define __pre __declspec("SAL_pre")
+
+ /*
+ __post __next_annotation
+
+ The next annotation applies in the postcondition state
+ */
+ #define __post __declspec("SAL_post")
+
+ /*
+ __precond(<expr>)
+
+ When <expr> is true, the next annotation applies in the precondition state
+ (currently not enabled)
+ */
+ #define __precond(expr) __pre
+
+ /*
+ __postcond(<expr>)
+
+ When <expr> is true, the next annotation applies in the postcondition state
+ (currently not enabled)
+ */
+ #define __postcond(expr) __post
+
+ /*
+ __exceptthat
+
+ Given a set of annotations Q containing __exceptthat maybeP, the effect of
+ the except clause is to erase any P or notP annotations (explicit or
+ implied) within Q at the same level of dereferencing that the except
+ clause appears, and to replace it with maybeP.
+
+ Example 1: __valid __exceptthat __maybenull on a pointer p means that the
+ pointer may be null, and is otherwise valid, thus overriding
+ the implicit notnull annotation implied by __valid on
+ pointers.
+
+ Example 2: __valid __deref __exceptthat __maybenull on an int **p means
+ that p is not null (implied by valid), but the elements
+ pointed to by p could be null, and are otherwise valid.
+ */
+ #define __exceptthat __declspec("SAL_except")
+ #define __execeptthat __exceptthat
+
+ /*
+ _refparam
+
+ Added to all out parameter macros to indicate that they are all reference
+ parameters.
+ */
+ #define __refparam __deref __notreadonly
+
+ /*
+ __inner_*
+
+ Helper macros that directly correspond to certain high-level annotations.
+
+ */
+
+ /*
+ Macros to classify the entrypoints and indicate their category.
+
+ Pre-defined control point categories include: RPC, LPC, DeviceDriver, UserToKernel, ISAPI, COM.
+
+ */
+ #define __inner_control_entrypoint(category) __declspec("SAL_entrypoint(controlEntry, "SPECSTRINGIZE(category)")")
+
+ /*
+ Pre-defined data entry point categories include: Registry, File, Network.
+ */
+ #define __inner_data_entrypoint(category) __declspec("SAL_entrypoint(dataEntry, "SPECSTRINGIZE(category)")")
+
+ #define __inner_success(expr) __declspec("SAL_success("SPECSTRINGIZE(expr)")")
+ #define __inner_checkReturn __declspec("SAL_checkReturn")
+ #define __inner_typefix(ctype) __declspec("SAL_typefix("SPECSTRINGIZE(ctype)")")
+ #define __inner_override __declspec("__override")
+ #define __inner_callback __declspec("__callback")
+ #define __inner_blocksOn(resource) __declspec("SAL_blocksOn("SPECSTRINGIZE(resource)")")
+ #define __inner_fallthrough_dec __inline __nothrow void __FallThrough() {}
+ #define __inner_fallthrough __FallThrough();
+
+#else
+ #define __null
+ #define __notnull
+ #define __maybenull
+ #define __readonly
+ #define __notreadonly
+ #define __maybereadonly
+ #define __valid
+ #define __notvalid
+ #define __maybevalid
+ #define __readableTo(extent)
+ #define __elem_readableTo(size)
+ #define __byte_readableTo(size)
+ #define __writableTo(size)
+ #define __elem_writableTo(size)
+ #define __byte_writableTo(size)
+ #define __deref
+ #define __pre
+ #define __post
+ #define __precond(expr)
+ #define __postcond(expr)
+ #define __exceptthat
+ #define __execeptthat
+ #define __inner_success(expr)
+ #define __inner_checkReturn
+ #define __inner_typefix(ctype)
+ #define __inner_override
+ #define __inner_callback
+ #define __inner_blocksOn(resource)
+ #define __inner_fallthrough_dec
+ #define __inner_fallthrough
+ #define __refparam
+ #define __inner_control_entrypoint(category)
+ #define __inner_data_entrypoint(category)
+#endif /* #if !defined(__midl) && defined(_PREFAST_) */
+
+/*
+-------------------------------------------------------------------------------
+Buffer Annotation Definitions
+
+Any of these may be used to directly annotate functions, but only one should
+be used for each parameter. To determine which annotation to use for a given
+buffer, use the table in the buffer annotations section.
+-------------------------------------------------------------------------------
+*/
+
+#define __ecount(size) __notnull __elem_writableTo(size)
+#define __bcount(size) __notnull __byte_writableTo(size)
+#define __in __pre __valid __pre __deref __readonly
+#define __in_ecount(size) __in __pre __elem_readableTo(size)
+#define __in_bcount(size) __in __pre __byte_readableTo(size)
+#define __in_z __in __pre __nullterminated
+#define __in_ecount_z(size) __in_ecount(size) __pre __nullterminated
+#define __in_bcount_z(size) __in_bcount(size) __pre __nullterminated
+#define __in_nz __in
+#define __in_ecount_nz(size) __in_ecount(size)
+#define __in_bcount_nz(size) __in_bcount(size)
+#define __out __ecount(1) __post __valid __refparam
+#define __out_ecount(size) __ecount(size) __post __valid __refparam
+#define __out_bcount(size) __bcount(size) __post __valid __refparam
+#define __out_ecount_part(size,length) __out_ecount(size) __post __elem_readableTo(length)
+#define __out_bcount_part(size,length) __out_bcount(size) __post __byte_readableTo(length)
+#define __out_ecount_full(size) __out_ecount_part(size,size)
+#define __out_bcount_full(size) __out_bcount_part(size,size)
+#define __out_z __post __valid __refparam __post __nullterminated
+#define __out_z_opt __post __valid __refparam __post __nullterminated __exceptthat __maybenull
+#define __out_ecount_z(size) __ecount(size) __post __valid __refparam __post __nullterminated
+#define __out_bcount_z(size) __bcount(size) __post __valid __refparam __post __nullterminated
+#define __out_ecount_part_z(size,length) __out_ecount_part(size,length) __post __nullterminated
+#define __out_bcount_part_z(size,length) __out_bcount_part(size,length) __post __nullterminated
+#define __out_ecount_full_z(size) __out_ecount_full(size) __post __nullterminated
+#define __out_bcount_full_z(size) __out_bcount_full(size) __post __nullterminated
+#define __out_nz __post __valid __refparam __post
+#define __out_nz_opt __post __valid __refparam __post __exceptthat __maybenull
+#define __out_ecount_nz(size) __ecount(size) __post __valid __refparam
+#define __out_bcount_nz(size) __bcount(size) __post __valid __refparam
+#define __inout __pre __valid __post __valid __refparam
+#define __inout_ecount(size) __out_ecount(size) __pre __valid
+#define __inout_bcount(size) __out_bcount(size) __pre __valid
+#define __inout_ecount_part(size,length) __out_ecount_part(size,length) __pre __valid __pre __elem_readableTo(length)
+#define __inout_bcount_part(size,length) __out_bcount_part(size,length) __pre __valid __pre __byte_readableTo(length)
+#define __inout_ecount_full(size) __inout_ecount_part(size,size)
+#define __inout_bcount_full(size) __inout_bcount_part(size,size)
+#define __inout_z __inout __pre __nullterminated __post __nullterminated
+#define __inout_ecount_z(size) __inout_ecount(size) __pre __nullterminated __post __nullterminated
+#define __inout_bcount_z(size) __inout_bcount(size) __pre __nullterminated __post __nullterminated
+#define __inout_nz __inout
+#define __inout_ecount_nz(size) __inout_ecount(size)
+#define __inout_bcount_nz(size) __inout_bcount(size)
+#define __ecount_opt(size) __ecount(size) __exceptthat __maybenull
+#define __bcount_opt(size) __bcount(size) __exceptthat __maybenull
+#define __in_opt __in __exceptthat __maybenull
+#define __in_ecount_opt(size) __in_ecount(size) __exceptthat __maybenull
+#define __in_bcount_opt(size) __in_bcount(size) __exceptthat __maybenull
+#define __in_z_opt __in_opt __pre __nullterminated
+#define __in_ecount_z_opt(size) __in_ecount_opt(size) __pre __nullterminated
+#define __in_bcount_z_opt(size) __in_bcount_opt(size) __pre __nullterminated
+#define __in_nz_opt __in_opt
+#define __in_ecount_nz_opt(size) __in_ecount_opt(size)
+#define __in_bcount_nz_opt(size) __in_bcount_opt(size)
+#define __out_opt __out __exceptthat __maybenull
+#define __out_ecount_opt(size) __out_ecount(size) __exceptthat __maybenull
+#define __out_bcount_opt(size) __out_bcount(size) __exceptthat __maybenull
+#define __out_ecount_part_opt(size,length) __out_ecount_part(size,length) __exceptthat __maybenull
+#define __out_bcount_part_opt(size,length) __out_bcount_part(size,length) __exceptthat __maybenull
+#define __out_ecount_full_opt(size) __out_ecount_full(size) __exceptthat __maybenull
+#define __out_bcount_full_opt(size) __out_bcount_full(size) __exceptthat __maybenull
+#define __out_ecount_z_opt(size) __out_ecount_opt(size) __post __nullterminated
+#define __out_bcount_z_opt(size) __out_bcount_opt(size) __post __nullterminated
+#define __out_ecount_part_z_opt(size,length) __out_ecount_part_opt(size,length) __post __nullterminated
+#define __out_bcount_part_z_opt(size,length) __out_bcount_part_opt(size,length) __post __nullterminated
+#define __out_ecount_full_z_opt(size) __out_ecount_full_opt(size) __post __nullterminated
+#define __out_bcount_full_z_opt(size) __out_bcount_full_opt(size) __post __nullterminated
+#define __out_ecount_nz_opt(size) __out_ecount_opt(size) __post __nullterminated
+#define __out_bcount_nz_opt(size) __out_bcount_opt(size) __post __nullterminated
+#define __inout_opt __inout __exceptthat __maybenull
+#define __inout_ecount_opt(size) __inout_ecount(size) __exceptthat __maybenull
+#define __inout_bcount_opt(size) __inout_bcount(size) __exceptthat __maybenull
+#define __inout_ecount_part_opt(size,length) __inout_ecount_part(size,length) __exceptthat __maybenull
+#define __inout_bcount_part_opt(size,length) __inout_bcount_part(size,length) __exceptthat __maybenull
+#define __inout_ecount_full_opt(size) __inout_ecount_full(size) __exceptthat __maybenull
+#define __inout_bcount_full_opt(size) __inout_bcount_full(size) __exceptthat __maybenull
+#define __inout_z_opt __inout_opt __pre __nullterminated __post __nullterminated
+#define __inout_ecount_z_opt(size) __inout_ecount_opt(size) __pre __nullterminated __post __nullterminated
+#define __inout_ecount_z_opt(size) __inout_ecount_opt(size) __pre __nullterminated __post __nullterminated
+#define __inout_bcount_z_opt(size) __inout_bcount_opt(size)
+#define __inout_nz_opt __inout_opt
+#define __inout_ecount_nz_opt(size) __inout_ecount_opt(size)
+#define __inout_bcount_nz_opt(size) __inout_bcount_opt(size)
+#define __deref_ecount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __elem_writableTo(size)
+#define __deref_bcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __byte_writableTo(size)
+#define __deref_out __deref_ecount(1) __post __deref __valid __refparam
+#define __deref_out_ecount(size) __deref_ecount(size) __post __deref __valid __refparam
+#define __deref_out_bcount(size) __deref_bcount(size) __post __deref __valid __refparam
+#define __deref_out_ecount_part(size,length) __deref_out_ecount(size) __post __deref __elem_readableTo(length)
+#define __deref_out_bcount_part(size,length) __deref_out_bcount(size) __post __deref __byte_readableTo(length)
+#define __deref_out_ecount_full(size) __deref_out_ecount_part(size,size)
+#define __deref_out_bcount_full(size) __deref_out_bcount_part(size,size)
+#define __deref_out_z __post __deref __valid __refparam __post __deref __nullterminated
+#define __deref_out_ecount_z(size) __deref_out_ecount(size) __post __deref __nullterminated
+#define __deref_out_bcount_z(size) __deref_out_ecount(size) __post __deref __nullterminated
+#define __deref_out_nz __deref_out
+#define __deref_out_ecount_nz(size) __deref_out_ecount(size)
+#define __deref_out_bcount_nz(size) __deref_out_ecount(size)
+#define __deref_inout __notnull __elem_readableTo(1) __pre __deref __valid __post __deref __valid __refparam
+#define __deref_inout_z __deref_inout __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_ecount(size) __deref_inout __pre __deref __elem_writableTo(size) __post __deref __elem_writableTo(size)
+#define __deref_inout_bcount(size) __deref_inout __pre __deref __byte_writableTo(size) __post __deref __byte_writableTo(size)
+#define __deref_inout_ecount_part(size,length) __deref_inout_ecount(size) __pre __deref __elem_readableTo(length) __post __deref __elem_readableTo(length)
+#define __deref_inout_bcount_part(size,length) __deref_inout_bcount(size) __pre __deref __byte_readableTo(length) __post __deref __byte_readableTo(length)
+#define __deref_inout_ecount_full(size) __deref_inout_ecount_part(size,size)
+#define __deref_inout_bcount_full(size) __deref_inout_bcount_part(size,size)
+#define __deref_inout_z __deref_inout __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_ecount_z(size) __deref_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_bcount_z(size) __deref_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_nz __deref_inout
+#define __deref_inout_ecount_nz(size) __deref_inout_ecount(size)
+#define __deref_inout_bcount_nz(size) __deref_inout_ecount(size)
+#define __deref_ecount_opt(size) __deref_ecount(size) __post __deref __exceptthat __maybenull
+#define __deref_bcount_opt(size) __deref_bcount(size) __post __deref __exceptthat __maybenull
+#define __deref_out_opt __deref_out __post __deref __exceptthat __maybenull
+#define __deref_out_ecount_opt(size) __deref_out_ecount(size) __post __deref __exceptthat __maybenull
+#define __deref_out_bcount_opt(size) __deref_out_bcount(size) __post __deref __exceptthat __maybenull
+#define __deref_out_ecount_part_opt(size,length) __deref_out_ecount_part(size,length) __post __deref __exceptthat __maybenull
+#define __deref_out_bcount_part_opt(size,length) __deref_out_bcount_part(size,length) __post __deref __exceptthat __maybenull
+#define __deref_out_ecount_full_opt(size) __deref_out_ecount_full(size) __post __deref __exceptthat __maybenull
+#define __deref_out_bcount_full_opt(size) __deref_out_bcount_full(size) __post __deref __exceptthat __maybenull
+#define __deref_out_z_opt __post __deref __valid __refparam __execeptthat __maybenull __post __deref __nullterminated
+#define __deref_out_ecount_z_opt(size) __deref_out_ecount_opt(size) __post __deref __nullterminated
+#define __deref_out_bcount_z_opt(size) __deref_out_bcount_opt(size) __post __deref __nullterminated
+#define __deref_out_nz_opt __deref_out_opt
+#define __deref_out_ecount_nz_opt(size) __deref_out_ecount_opt(size)
+#define __deref_out_bcount_nz_opt(size) __deref_out_bcount_opt(size)
+#define __deref_inout_opt __deref_inout __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_ecount_opt(size) __deref_inout_ecount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_bcount_opt(size) __deref_inout_bcount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_ecount_part_opt(size,length) __deref_inout_ecount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_bcount_part_opt(size,length) __deref_inout_bcount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_ecount_full_opt(size) __deref_inout_ecount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_bcount_full_opt(size) __deref_inout_bcount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#define __deref_inout_z_opt __deref_inout_opt __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_ecount_z_opt(size) __deref_inout_ecount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_bcount_z_opt(size) __deref_inout_bcount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_inout_nz_opt __deref_inout_opt
+#define __deref_inout_ecount_nz_opt(size) __deref_inout_ecount_opt(size)
+#define __deref_inout_bcount_nz_opt(size) __deref_inout_bcount_opt(size)
+#define __deref_opt_ecount(size) __deref_ecount(size) __exceptthat __maybenull
+#define __deref_opt_bcount(size) __deref_bcount(size) __exceptthat __maybenull
+#define __deref_opt_out __deref_out __exceptthat __maybenull
+#define __deref_opt_out_z __deref_opt_out __post __deref __nullterminated
+#define __deref_opt_out_ecount(size) __deref_out_ecount(size) __exceptthat __maybenull
+#define __deref_opt_out_bcount(size) __deref_out_bcount(size) __exceptthat __maybenull
+#define __deref_opt_out_ecount_part(size,length) __deref_out_ecount_part(size,length) __exceptthat __maybenull
+#define __deref_opt_out_bcount_part(size,length) __deref_out_bcount_part(size,length) __exceptthat __maybenull
+#define __deref_opt_out_ecount_full(size) __deref_out_ecount_full(size) __exceptthat __maybenull
+#define __deref_opt_out_bcount_full(size) __deref_out_bcount_full(size) __exceptthat __maybenull
+#define __deref_opt_inout __deref_inout __exceptthat __maybenull
+#define __deref_opt_inout_ecount(size) __deref_inout_ecount(size) __exceptthat __maybenull
+#define __deref_opt_inout_bcount(size) __deref_inout_bcount(size) __exceptthat __maybenull
+#define __deref_opt_inout_ecount_part(size,length) __deref_inout_ecount_part(size,length) __exceptthat __maybenull
+#define __deref_opt_inout_bcount_part(size,length) __deref_inout_bcount_part(size,length) __exceptthat __maybenull
+#define __deref_opt_inout_ecount_full(size) __deref_inout_ecount_full(size) __exceptthat __maybenull
+#define __deref_opt_inout_bcount_full(size) __deref_inout_bcount_full(size) __exceptthat __maybenull
+#define __deref_opt_inout_z __deref_opt_inout __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_ecount_z(size) __deref_opt_inout_ecount(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_bcount_z(size) __deref_opt_inout_bcount(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_nz __deref_opt_inout
+#define __deref_opt_inout_ecount_nz(size) __deref_opt_inout_ecount(size)
+#define __deref_opt_inout_bcount_nz(size) __deref_opt_inout_bcount(size)
+#define __deref_opt_ecount_opt(size) __deref_ecount_opt(size) __exceptthat __maybenull
+#define __deref_opt_bcount_opt(size) __deref_bcount_opt(size) __exceptthat __maybenull
+#define __deref_opt_out_opt __deref_out_opt __exceptthat __maybenull
+#define __deref_opt_out_ecount_opt(size) __deref_out_ecount_opt(size) __exceptthat __maybenull
+#define __deref_opt_out_bcount_opt(size) __deref_out_bcount_opt(size) __exceptthat __maybenull
+#define __deref_opt_out_ecount_part_opt(size,length) __deref_out_ecount_part_opt(size,length) __exceptthat __maybenull
+#define __deref_opt_out_bcount_part_opt(size,length) __deref_out_bcount_part_opt(size,length) __exceptthat __maybenull
+#define __deref_opt_out_ecount_full_opt(size) __deref_out_ecount_full_opt(size) __exceptthat __maybenull
+#define __deref_opt_out_bcount_full_opt(size) __deref_out_bcount_full_opt(size) __exceptthat __maybenull
+#define __deref_opt_out_z_opt __post __deref __valid __refparam __exceptthat __maybenull __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull __post __deref __nullterminated
+#define __deref_opt_out_ecount_z_opt(size) __deref_opt_out_ecount_opt(size) __post __deref __nullterminated
+#define __deref_opt_out_bcount_z_opt(size) __deref_opt_out_bcount_opt(size) __post __deref __nullterminated
+#define __deref_opt_out_nz_opt __deref_opt_out_opt
+#define __deref_opt_out_ecount_nz_opt(size) __deref_opt_out_ecount_opt(size)
+#define __deref_opt_out_bcount_nz_opt(size) __deref_opt_out_bcount_opt(size)
+#define __deref_opt_inout_opt __deref_inout_opt __exceptthat __maybenull
+#define __deref_opt_inout_ecount_opt(size) __deref_inout_ecount_opt(size) __exceptthat __maybenull
+#define __deref_opt_inout_bcount_opt(size) __deref_inout_bcount_opt(size) __exceptthat __maybenull
+#define __deref_opt_inout_ecount_part_opt(size,length) __deref_inout_ecount_part_opt(size,length) __exceptthat __maybenull
+#define __deref_opt_inout_bcount_part_opt(size,length) __deref_inout_bcount_part_opt(size,length) __exceptthat __maybenull
+#define __deref_opt_inout_ecount_full_opt(size) __deref_inout_ecount_full_opt(size) __exceptthat __maybenull
+#define __deref_opt_inout_bcount_full_opt(size) __deref_inout_bcount_full_opt(size) __exceptthat __maybenull
+#define __deref_opt_inout_z_opt __deref_opt_inout_opt __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_ecount_z_opt(size) __deref_opt_inout_ecount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_bcount_z_opt(size) __deref_opt_inout_bcount_opt(size) __pre __deref __nullterminated __post __deref __nullterminated
+#define __deref_opt_inout_nz_opt __deref_opt_inout_opt
+#define __deref_opt_inout_ecount_nz_opt(size) __deref_opt_inout_ecount_opt(size)
+#define __deref_opt_inout_bcount_nz_opt(size) __deref_opt_inout_bcount_opt(size)
+
+/*
+-------------------------------------------------------------------------------
+Advanced Annotation Definitions
+
+Any of these may be used to directly annotate functions, and may be used in
+combination with each other or with regular buffer macros. For an explanation
+of each annotation, see the advanced annotations section.
+-------------------------------------------------------------------------------
+*/
+
+#define __success(expr) __inner_success(expr)
+#define __nullterminated __readableTo(sentinel(0))
+#define __nullnullterminated
+#define __reserved __pre __null
+#define __checkReturn __inner_checkReturn
+#define __typefix(ctype) __inner_typefix(ctype)
+#define __override __inner_override
+#define __callback __inner_callback
+#define __format_string
+#define __blocksOn(resource) __inner_blocksOn(resource)
+#define __control_entrypoint(category) __inner_control_entrypoint(category)
+#define __data_entrypoint(category) __inner_data_entrypoint(category)
+
+#ifndef __fallthrough
+ __inner_fallthrough_dec
+ #define __fallthrough __inner_fallthrough
+#endif
+
+#ifndef __analysis_assume
+#ifdef _PREFAST_
+#define __analysis_assume(expr) __assume(expr)
+#else
+#define __analysis_assume(expr)
+#endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
diff --git a/core/src/fxge/Microsoft SDK/include/specstrings.h b/core/src/fxge/Microsoft SDK/include/specstrings.h
index 00cdd332ec..27a589a985 100644
--- a/core/src/fxge/Microsoft SDK/include/specstrings.h
+++ b/core/src/fxge/Microsoft SDK/include/specstrings.h
@@ -1,978 +1,978 @@
-/***************************************************************\
-* *
-* SpecStrings.h - markers for documenting the semantics of APIs *
-* *
-* Version 1.0 *
-* *
-* Copyright (c) Microsoft Corporation. All rights reserved. *
-* *
-\***************************************************************/
-
-// @@BEGIN_DDKSPLIT
-
-// -------------------------------------------------------------------------------
-// Introduction
-//
-// SpecStrings.h provides a set of annotations to describe how a function uses its
-// parameters - the assumptions it makes about them, and the guarantees it makes
-// upon finishing.
-//
-// Annotations may be placed before either a function parameter's type or its return
-// type, and describe the function's behavior regarding the parameter or return value.
-// There are two classes of annotations: buffer annotations and advanced annotations.
-// Buffer annotations describe how functions use their pointer parameters, and
-// advanced annotations either describe complex/unusual buffer behavior, or provide
-// additional information about a parameter that is not otherwise expressible.
-//
-// -------------------------------------------------------------------------------
-// Buffer Annotations
-//
-// The most important annotations in SpecStrings.h provide a consistent way to annotate
-// buffer parameters or return values for a function. Each of these annotations describes
-// a single buffer (which could be a string, a fixed-length or variable-length array,
-// or just a pointer) that the function interacts with: where it is, how large it is,
-// how much is initialized, and what the function does with it.
-//
-// The appropriate macro for a given buffer can be constructed using the table below.
-// Just pick the appropriate values from each category, and combine them together
-// with a leading underscore. Some combinations of values do not make sense as buffer
-// annotations. Only meaningful annotations can be added to your code; for a list of
-// these, see the buffer annotation definitions section.
-//
-// Only a single buffer annotation should be used for each parameter.
-//
-// |------------|------------|---------|--------|----------|---------------|
-// | Level | Usage | Size | Output | Optional | Parameters |
-// |------------|------------|---------|--------|----------|---------------|
-// | <> | <> | <> | <> | <> | <> |
-// | _deref | _in | _ecount | _full | _opt | (size) |
-// | _deref_opt | _out | _bcount | _part | | (size,length) |
-// | | _inout | | | | |
-// | | | | | | |
-// |------------|------------|---------|--------|----------|---------------|
-//
-// Level: Describes the buffer pointer's level of indirection from the parameter or
-// return value 'p'.
-//
-// <> : p is the buffer pointer.
-// _deref : *p is the buffer pointer. p must not be NULL.
-// _deref_opt : *p may be the buffer pointer. p may be NULL, in which case the rest of
-// the annotation is ignored.
-//
-// Usage: Describes how the function uses the buffer.
-//
-// <> : The buffer is not accessed. If used on the return value or with _deref, the
-// function will provide the buffer, and it will be uninitialized at exit.
-// Otherwise, the caller must provide the buffer. This should only be used
-// for alloc and free functions.
-// _in : The function will only read from the buffer. The caller must provide the
-// buffer and initialize it.
-// _out : The function will only write to the buffer. If used on the return value or
-// with _deref, the function will provide the buffer and initialize it.
-// Otherwise, the caller must provide the buffer, and the function will
-// initialize it.
-// _inout : The function may freely read from and write to the buffer. The caller must
-// provide the buffer and initialize it. If used with _deref, the buffer may
-// be reallocated by the function.
-//
-// Size: Describes the total size of the buffer. This may be less than the space actually
-// allocated for the buffer, in which case it describes the accessible amount.
-//
-// <> : No buffer size is given. If the type specifies the buffer size (such as
-// with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is one
-// element long. Must be used with _in, _out, or _inout.
-// _ecount : The buffer size is an explicit element count.
-// _bcount : The buffer size is an explicit byte count.
-//
-// Output: Describes how much of the buffer will be initialized by the function. For
-// _inout buffers, this also describes how much is initialized at entry. Omit this
-// category for _in buffers; they must be fully initialized by the caller.
-//
-// <> : The type specifies how much is initialized. For instance, a function initializing
-// an LPWSTR must NULL-terminate the string.
-// _full : The function initializes the entire buffer.
-// _part : The function initializes part of the buffer, and explicitly indicates how much.
-//
-// Optional: Describes if the buffer itself is optional.
-//
-// <> : The pointer to the buffer must not be NULL.
-// _opt : The pointer to the buffer might be NULL. It will be checked before being dereferenced.
-//
-// Parameters: Gives explicit counts for the size and length of the buffer.
-//
-// <> : There is no explicit count. Use when neither _ecount nor _bcount is used.
-// (size) : Only the buffer's total size is given. Use with _ecount or _bcount but not _part.
-// (size,length) : The buffer's total size and initialized length are given. Use with _ecount_part
-// and _bcount_part.
-//
-// -------------------------------------------------------------------------------
-// Buffer Annotation Examples
-//
-// LWSTDAPI_(BOOL) StrToIntExA(
-// LPCSTR pszString, // No annotation required, const implies __in.
-// DWORD dwFlags,
-// __out int *piRet // A pointer whose dereference will be filled in.
-// );
-//
-// void MyPaintingFunction(
-// __in HWND hwndControl, // An initialized read-only parameter.
-// __in_opt HDC hdcOptional, // An initialized read-only parameter that might be NULL.
-// __inout IPropertyStore *ppsStore // An initialized parameter that may be freely used
-// // and modified.
-// );
-//
-// LWSTDAPI_(BOOL) PathCompactPathExA(
-// __out_ecount(cchMax) LPSTR pszOut, // A string buffer with cch elements that will
-// // be NULL terminated on exit.
-// LPCSTR pszSrc, // No annotation required, const implies __in.
-// UINT cchMax,
-// DWORD dwFlags
-// );
-//
-// HRESULT SHLocalAllocBytes(
-// size_t cb,
-// __deref_bcount(cb) T **ppv // A pointer whose dereference will be set to an
-// // uninitialized buffer with cb bytes.
-// );
-//
-// __inout_bcount_full(cb) : A buffer with cb elements that is fully initialized at
-// entry and exit, and may be written to by this function.
-//
-// __out_ecount_part(count, *countOut) : A buffer with count elements that will be
-// partially initialized by this function. The function indicates how much it
-// initialized by setting *countOut.
-//
-// -------------------------------------------------------------------------------
-// Advanced Annotations
-//
-// Advanced annotations describe behavior that is not expressible with the regular
-// buffer macros. These may be used either to annotate buffer parameters that involve
-// complex or conditional behavior, or to enrich existing annotations with additional
-// information.
-//
-// __success(expr) f :
-// <expr> indicates whether function f succeeded or not. If <expr> is true at exit,
-// all the function's guarantees (as given by other annotations) must hold. If <expr>
-// is false at exit, the caller should not expect any of the function's guarantees
-// to hold. If not used, the function must always satisfy its guarantees. Added
-// automatically to functions that indicate success in standard ways, such as by
-// returning an HRESULT.
-//
-// __out_awcount(expr, size) p :
-// Pointer p is a buffer whose size may be given in either bytes or elements. If
-// <expr> is true, this acts like __out_bcount. If <expr> is false, this acts
-// like __out_ecount. This should only be used to annotate old APIs.
-//
-// __in_awcount(expr, size) p :
-// Pointer p is a buffer whose size may be given in either bytes or elements. If
-// <expr> is true, this acts like __in_bcount. If <expr> is false, this acts
-// like __in_ecount. This should only be used to annotate old APIs.
-//
-// __nullterminated p :
-// Pointer p is a buffer that may be read or written up to and including the first
-// NULL character or pointer. May be used on typedefs, which marks valid (properly
-// initialized) instances of that type as being NULL-terminated.
-//
-// __nullnullterminated p :
-// Pointer p is a buffer that may be read or written up to and including the first
-// sequence of two NULL characters or pointers. May be used on typedefs, which marks
-// valid instances of that type as being double-NULL terminated.
-//
-// __reserved v :
-// Value v must be 0/NULL, reserved for future use.
-//
-// __checkReturn v :
-// Return value v must not be ignored by callers of this function.
-//
-// __typefix(ctype) v :
-// Value v should be treated as an instance of ctype, rather than its declared type.
-//
-// __override f :
-// Specify C#-style 'override' behaviour for overriding virtual methods.
-//
-// __callback f :
-// Function f can be used as a function pointer.
-//
-// __format_string p :
-// Pointer p is a string that contains % markers in the style of printf.
-//
-// __blocksOn(resource) f :
-// Function f blocks on the resource 'resource'.
-//
-// __fallthrough :
-// Annotates switch statement labels where fall-through is desired, to distinguish
-// from forgotten break statements.
-//
-// -------------------------------------------------------------------------------
-// Advanced Annotation Examples
-//
-// __success(return == TRUE) LWSTDAPI_(BOOL)
-// PathCanonicalizeA(__out_ecount(MAX_PATH) LPSTR pszBuf, LPCSTR pszPath) :
-// pszBuf is only guaranteed to be NULL-terminated when TRUE is returned.
-//
-// typedef __nullterminated WCHAR* LPWSTR : Initialized LPWSTRs are NULL-terminated strings.
-//
-// __out_ecount(cch) __typefix(LPWSTR) void *psz : psz is a buffer parameter which will be
-// a NULL-terminated WCHAR string at exit, and which initially contains cch WCHARs.
-//
-// -------------------------------------------------------------------------------
-
-// @@END_DDKSPLIT
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // #if _MSC_VER > 1000
-
-#define __specstrings
-
-#ifdef __cplusplus
-#ifndef __nothrow
-# define __nothrow __declspec(nothrow)
-#endif
-extern "C" {
-#else
-#ifndef __nothrow
-# define __nothrow
-#endif
-#endif // #ifdef __cplusplus
-
-// @@BEGIN_DDKSPLIT
-
-// -------------------------------------------------------------------------------
-// Helper Macro Definitions
-//
-// These express behavior common to many of the high-level annotations.
-// DO NOT USE THESE IN YOUR CODE.
-// -------------------------------------------------------------------------------
-
-// The helper annotations are only understood by the compiler version used by various
-// defect detection tools. When the regular compiler is running, they are defined into
-// nothing, and do not affect the compiled code.
-#if (_MSC_VER >= 1000) && !defined(MIDL_PASS) && defined(_PREFAST_)
-
- // In the primitive __declspec("SAL_*") annotations "SAL" stands for Standard
- // Annotation Language. These __declspec("SAL_*") annotations are the
- // primitives the compiler understands and all high-level SpecString MACROs
- // will decompose into these primivates.
-
- #define SPECSTRINGIZE( x ) #x
-
- //
- // __null p
- // __notnull p
- // __maybenull p
- //
- // Annotates a pointer p. States that pointer p is null. Commonly used
- // in the negated form __notnull or the possibly null form __maybenull.
- //
- #define __null __declspec("SAL_null")
- #define __notnull __declspec("SAL_notnull")
- #define __maybenull __declspec("SAL_maybenull")
-
- //
- // __readonly l
- // __notreadonly l
- // __mabyereadonly l
- //
- // Annotates a location l. States that location l is not modified after
- // this point. If the annotation is placed on the precondition state of
- // a function, the restriction only applies until the postcondition state
- // of the function. __maybereadonly states that the annotated location
- // may be modified, whereas __notreadonly states that a location must be
- // modified.
- //
- #define __readonly __declspec("SAL_readonly")
- #define __notreadonly __declspec("SAL_notreadonly")
- #define __maybereadonly __declspec("SAL_maybereadonly")
-
- //
- // __valid v
- // __notvalid v
- // __maybevalid v
- //
- // Annotates any value v. States that the value satisfies all properties of
- // valid values of its type. For example, for a string buffer, valid means
- // that the buffer pointer is either NULL or points to a NULL-terminated string.
- //
- #define __valid __declspec("SAL_valid")
- #define __notvalid __declspec("SAL_notvalid")
- #define __maybevalid __declspec("SAL_maybevalid")
-
- //
- // __readableTo(extent) p
- //
- // Annotates a buffer pointer p. If the buffer can be read, extent describes
- // how much of the buffer is readable. For a reader of the buffer, this is
- // an explicit permission to read up to that amount, rather than a restriction to
- // read only up to it.
- //
- #define __readableTo(extent) __declspec("SAL_readableTo("SPECSTRINGIZE(extent)")")
-
- //
- // __elem_readableTo(size)
- //
- // Annotates a buffer pointer p as being readable to size elements.
- //
- #define __elem_readableTo(size) __declspec("SAL_readableTo(elementCount("SPECSTRINGIZE(size)"))")
-
- //
- // __byte_readableTo(size)
- //
- // Annotates a buffer pointer p as being readable to size bytes.
- //
- #define __byte_readableTo(size) __declspec("SAL_readableTo(byteCount("SPECSTRINGIZE(size)"))")
-
- //
- // __writableTo(extent) p
- //
- // Annotates a buffer pointer p. If the buffer can be modified, extent
- // describes how much of the buffer is writable (usually the allocation
- // size). For a writer of the buffer, this is an explicit permission to
- // write up to that amount, rather than a restriction to write only up to it.
- //
- #define __writableTo(size) __declspec("SAL_writableTo("SPECSTRINGIZE(size)")")
-
- //
- // __elem_writableTo(size)
- //
- // Annotates a buffer pointer p as being writable to size elements.
- //
- #define __elem_writableTo(size) __declspec("SAL_writableTo(elementCount("SPECSTRINGIZE(size)"))")
-
- //
- // __byte_writableTo(size)
- //
- // Annotates a buffer pointer p as being writable to size bytes.
- //
- #define __byte_writableTo(size) __declspec("SAL_writableTo(byteCount("SPECSTRINGIZE(size)"))")
-
- //
- // __deref p
- //
- // Annotates a pointer p. The next annotation applies one dereference down
- // in the type. If readableTo(p, size) then the next annotation applies to
- // all elements *(p+i) for which i satisfies the size. If p is a pointer
- // to a struct, the next annotation applies to all fields of the struct.
- //
- #define __deref __declspec("SAL_deref")
-
- //
- // __pre __next_annotation
- //
- // The next annotation applies in the precondition state
- //
- #define __pre __declspec("SAL_pre")
-
- //
- // __post __next_annotation
- //
- // The next annotation applies in the postcondition state
- //
- #define __post __declspec("SAL_post")
-
- //
- // __precond(<expr>)
- //
- // When <expr> is true, the next annotation applies in the precondition state
- // (currently not enabled)
- //
- #define __precond(expr) __pre
-
- //
- // __postcond(<expr>)
- //
- // When <expr> is true, the next annotation applies in the postcondition state
- // (currently not enabled)
- //
- #define __postcond(expr) __post
-
- //
- // __exceptthat
- //
- // Given a set of annotations Q containing __exceptthat maybeP, the effect of
- // the except clause is to erase any P or notP annotations (explicit or
- // implied) within Q at the same level of dereferencing that the except
- // clause appears, and to replace it with maybeP.
- //
- // Example 1: __valid __exceptthat __maybenull on a pointer p means that the
- // pointer may be null, and is otherwise valid, thus overriding
- // the implicit notnull annotation implied by __valid on
- // pointers.
- //
- // Example 2: __valid __deref __exceptthat __maybenull on an int **p means
- // that p is not null (implied by valid), but the elements
- // pointed to by p could be null, and are otherwise valid.
- //
- #define __exceptthat __declspec("SAL_except")
-
- //
- // _refparam
- //
- // Added to all out parameter macros to indicate that they are all reference
- // parameters.
- //
- #define __refparam __deref __notreadonly
-
- //
- // __inner_*
- //
- // Helper macros that directly correspond to certain high-level annotations.
- //
- //
-
- // Macros to classify the entrypoints and indicate their category.
- //
- //
- // Pre-defined control point categories include: RPC, LPC, DeviceDriver, UserToKernel, ISAPI, COM.
- //
- #define __inner_control_entrypoint(category) __declspec("SAL_entrypoint(controlEntry, "SPECSTRINGIZE(category)")")
-
- //
- // Pre-defined data entry point categories include: Registry, File, Network.
- //
- #define __inner_data_entrypoint(category) __declspec("SAL_entrypoint(dataEntry, "SPECSTRINGIZE(category)")")
-
- #define __inner_success(expr) __declspec("SAL_success("SPECSTRINGIZE(expr)")")
- #define __inner_checkReturn __declspec("SAL_checkReturn")
- #define __inner_typefix(ctype) __declspec("SAL_typefix("SPECSTRINGIZE(ctype)")")
- #define __inner_override __declspec("__override")
- #define __inner_callback __declspec("__callback")
- #define __inner_blocksOn(resource) __declspec("SAL_blocksOn("SPECSTRINGIZE(resource)")")
- #define __inner_fallthrough_dec __inline __nothrow void __FallThrough() {}
- #define __inner_fallthrough __FallThrough();
-
-#else
-
-// @@END_DDKSPLIT
-
-#ifndef __null
- #define __null
-#endif
-#ifndef __notnull
- #define __notnull
-#endif
-#ifndef __maybenull
- #define __maybenull
-#endif
-#ifndef __readonly
- #define __readonly
-#endif
-#ifndef __notreadonly
- #define __notreadonly
-#endif
-#ifndef __maybereadonly
- #define __maybereadonly
-#endif
-#ifndef __valid
- #define __valid
-#endif
-#ifndef __notvalid
- #define __notvalid
-#endif
-#ifndef __maybevalid
- #define __maybevalid
-#endif
-#ifndef __readableTo
- #define __readableTo(extent)
-#endif
-#ifndef __elem_readableTo
- #define __elem_readableTo(size)
-#endif
-#ifndef __byte_readableTo
- #define __byte_readableTo(size)
-#endif
-#ifndef __writableTo
- #define __writableTo(size)
-#endif
-#ifndef __elem_writableTo
- #define __elem_writableTo(size)
-#endif
-#ifndef __byte_writableTo
- #define __byte_writableTo(size)
-#endif
-#ifndef __deref
- #define __deref
-#endif
-#ifndef __pre
- #define __pre
-#endif
-#ifndef __post
- #define __post
-#endif
-#ifndef __precond
- #define __precond(expr)
-#endif
-#ifndef __postcond
- #define __postcond(expr)
-#endif
-#ifndef __exceptthat
- #define __exceptthat
-#endif
-#ifndef __inner_success
- #define __inner_success(expr)
-#endif
-#ifndef __inner_checkReturn
- #define __inner_checkReturn
-#endif
-#ifndef __inner_typefix
- #define __inner_typefix(ctype)
-#endif
-#ifndef __inner_override
- #define __inner_override
-#endif
-#ifndef __inner_callback
- #define __inner_callback
-#endif
-#ifndef __inner_blocksOn
- #define __inner_blocksOn(resource)
-#endif
-#ifndef __inner_fallthrough_dec
- #define __inner_fallthrough_dec
-#endif
-#ifndef __inner_fallthrough
- #define __inner_fallthrough
-#endif
-#ifndef __refparam
- #define __refparam
-#endif
-#ifndef __inner_control_entrypoint
- #define __inner_control_entrypoint(category)
-#endif
-#ifndef __inner_data_entrypoint
- #define __inner_data_entrypoint(category)
-#endif
-// @@BEGIN_DDKSPLIT
-#endif // #if (_MSC_VER >= 1000) && !defined(MIDL_PASS) && defined(_PREFAST_)
-// -------------------------------------------------------------------------------
-// Buffer Annotation Definitions
-//
-// Any of these may be used to directly annotate functions, but only one should
-// be used for each parameter. To determine which annotation to use for a given
-// buffer, use the table in the buffer annotations section.
-// -------------------------------------------------------------------------------
-// @@END_DDKSPLIT
-
-#ifndef __ecount
-#define __ecount(size) __notnull __elem_writableTo(size)
-#endif
-#ifndef __bcount
-#define __bcount(size) __notnull __byte_writableTo(size)
-#endif
-#ifndef __in
-#define __in __pre __valid __pre __deref __readonly
-#endif
-#ifndef __in_ecount
-#define __in_ecount(size) __in __pre __elem_readableTo(size)
-#endif
-#ifndef __in_bcount
-#define __in_bcount(size) __in __pre __byte_readableTo(size)
-#endif
-#ifndef __out
-#define __out __ecount(1) __post __valid __refparam
-#endif
-#ifndef __out_ecount
-#define __out_ecount(size) __ecount(size) __post __valid __refparam
-#endif
-#ifndef __out_bcount
-#define __out_bcount(size) __bcount(size) __post __valid __refparam
-#endif
-#ifndef __out_ecount_part
-#define __out_ecount_part(size,length) __out_ecount(size) __post __elem_readableTo(length)
-#endif
-#ifndef __out_bcount_part
-#define __out_bcount_part(size,length) __out_bcount(size) __post __byte_readableTo(length)
-#endif
-#ifndef __out_ecount_full
-#define __out_ecount_full(size) __out_ecount_part(size,size)
-#endif
-#ifndef __out_bcount_full
-#define __out_bcount_full(size) __out_bcount_part(size,size)
-#endif
-#ifndef __inout
-#define __inout __pre __valid __post __valid __refparam
-#endif
-#ifndef __inout_ecount
-#define __inout_ecount(size) __out_ecount(size) __pre __valid
-#endif
-#ifndef __inout_bcount
-#define __inout_bcount(size) __out_bcount(size) __pre __valid
-#endif
-#ifndef __inout_ecount_part
-#define __inout_ecount_part(size,length) __out_ecount_part(size,length) __pre __valid __pre __elem_readableTo(length)
-#endif
-#ifndef __inout_bcount_part
-#define __inout_bcount_part(size,length) __out_bcount_part(size,length) __pre __valid __pre __byte_readableTo(length)
-#endif
-#ifndef __inout_ecount_full
-#define __inout_ecount_full(size) __inout_ecount_part(size,size)
-#endif
-#ifndef __inout_bcount_full
-#define __inout_bcount_full(size) __inout_bcount_part(size,size)
-#endif
-
-#ifndef __ecount_opt
-#define __ecount_opt(size) __ecount(size) __exceptthat __maybenull
-#endif
-#ifndef __bcount_opt
-#define __bcount_opt(size) __bcount(size) __exceptthat __maybenull
-#endif
-#ifndef __in_opt
-#define __in_opt __in __exceptthat __maybenull
-#endif
-#ifndef __in_ecount_opt
-#define __in_ecount_opt(size) __in_ecount(size) __exceptthat __maybenull
-#endif
-#ifndef __in_bcount_opt
-#define __in_bcount_opt(size) __in_bcount(size) __exceptthat __maybenull
-#endif
-#ifndef __out_opt
-#define __out_opt __out __exceptthat __maybenull
-#endif
-#ifndef __out_ecount_opt
-#define __out_ecount_opt(size) __out_ecount(size) __exceptthat __maybenull
-#endif
-#ifndef __out_bcount_opt
-#define __out_bcount_opt(size) __out_bcount(size) __exceptthat __maybenull
-#endif
-#ifndef __out_ecount_part_opt
-#define __out_ecount_part_opt(size,length) __out_ecount_part(size,length) __exceptthat __maybenull
-#endif
-#ifndef __out_bcount_part_opt
-#define __out_bcount_part_opt(size,length) __out_bcount_part(size,length) __exceptthat __maybenull
-#endif
-#ifndef __out_ecount_full_opt
-#define __out_ecount_full_opt(size) __out_ecount_full(size) __exceptthat __maybenull
-#endif
-#ifndef __out_bcount_full_opt
-#define __out_bcount_full_opt(size) __out_bcount_full(size) __exceptthat __maybenull
-#endif
-#ifndef __inout_opt
-#define __inout_opt __inout __exceptthat __maybenull
-#endif
-#ifndef __inout_ecount_opt
-#define __inout_ecount_opt(size) __inout_ecount(size) __exceptthat __maybenull
-#endif
-#ifndef __inout_bcount_opt
-#define __inout_bcount_opt(size) __inout_bcount(size) __exceptthat __maybenull
-#endif
-#ifndef __inout_ecount_part_opt
-#define __inout_ecount_part_opt(size,length) __inout_ecount_part(size,length) __exceptthat __maybenull
-#endif
-#ifndef __inout_bcount_part_opt
-#define __inout_bcount_part_opt(size,length) __inout_bcount_part(size,length) __exceptthat __maybenull
-#endif
-#ifndef __inout_ecount_full_opt
-#define __inout_ecount_full_opt(size) __inout_ecount_full(size) __exceptthat __maybenull
-#endif
-#ifndef __inout_bcount_full_opt
-#define __inout_bcount_full_opt(size) __inout_bcount_full(size) __exceptthat __maybenull
-#endif
-
-#ifndef __deref_ecount
-#define __deref_ecount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __elem_writableTo(size)
-#endif
-#ifndef __deref_bcount
-#define __deref_bcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __byte_writableTo(size)
-#endif
-#ifndef __deref_in
-#define __deref_in __in __pre __deref __deref __readonly
-#endif
-#ifndef __deref_in_ecount
-#define __deref_in_ecount(size) __deref_in __pre __deref __elem_readableTo(size)
-#endif
-#ifndef __deref_in_bcount
-#define __deref_in_bcount(size) __deref_in __pre __deref __byte_readableTo(size)
-#endif
-#ifndef __deref_out
-#define __deref_out __deref_ecount(1) __post __deref __valid __refparam
-#endif
-#ifndef __deref_out_ecount
-#define __deref_out_ecount(size) __deref_ecount(size) __post __deref __valid __refparam
-#endif
-#ifndef __deref_out_bcount
-#define __deref_out_bcount(size) __deref_bcount(size) __post __deref __valid __refparam
-#endif
-#ifndef __deref_out_ecount_part
-#define __deref_out_ecount_part(size,length) __deref_out_ecount(size) __post __deref __elem_readableTo(length)
-#endif
-#ifndef __deref_out_bcount_part
-#define __deref_out_bcount_part(size,length) __deref_out_bcount(size) __post __deref __byte_readableTo(length)
-#endif
-#ifndef __deref_out_ecount_full
-#define __deref_out_ecount_full(size) __deref_out_ecount_part(size,size)
-#endif
-#ifndef __deref_out_bcount_full
-#define __deref_out_bcount_full(size) __deref_out_bcount_part(size,size)
-#endif
-#ifndef __deref_inout
-#define __deref_inout __notnull __elem_readableTo(1) __pre __deref __valid __post __deref __valid __refparam
-#endif
-#ifndef __deref_inout_ecount
-#define __deref_inout_ecount(size) __deref_inout __pre __deref __elem_writableTo(size) __post __deref __elem_writableTo(size)
-#endif
-#ifndef __deref_inout_bcount
-#define __deref_inout_bcount(size) __deref_inout __pre __deref __byte_writableTo(size) __post __deref __byte_writableTo(size)
-#endif
-#ifndef __deref_inout_ecount_part
-#define __deref_inout_ecount_part(size,length) __deref_inout_ecount(size) __pre __deref __elem_readableTo(length) __post __deref __elem_readableTo(length)
-#endif
-#ifndef __deref_inout_bcount_part
-#define __deref_inout_bcount_part(size,length) __deref_inout_bcount(size) __pre __deref __byte_readableTo(length) __post __deref __byte_readableTo(length)
-#endif
-#ifndef __deref_inout_ecount_full
-#define __deref_inout_ecount_full(size) __deref_inout_ecount_part(size,size)
-#endif
-#ifndef __deref_inout_bcount_full
-#define __deref_inout_bcount_full(size) __deref_inout_bcount_part(size,size)
-#endif
-
-#ifndef __deref_ecount_opt
-#define __deref_ecount_opt(size) __deref_ecount(size) __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_bcount_opt
-#define __deref_bcount_opt(size) __deref_bcount(size) __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_in_opt
-#define __deref_in_opt __deref_in __pre __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_in_ecount_opt
-#define __deref_in_ecount_opt(size) __deref_in_ecount(size) __pre __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_in_bcount_opt
-#define __deref_in_bcount_opt(size) __deref_in_bcount(size) __pre __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_out_opt
-#define __deref_out_opt __deref_out __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_out_ecount_opt
-#define __deref_out_ecount_opt(size) __deref_out_ecount(size) __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_out_bcount_opt
-#define __deref_out_bcount_opt(size) __deref_out_bcount(size) __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_out_ecount_part_opt
-#define __deref_out_ecount_part_opt(size,length) __deref_out_ecount_part(size,length) __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_out_bcount_part_opt
-#define __deref_out_bcount_part_opt(size,length) __deref_out_bcount_part(size,length) __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_out_ecount_full_opt
-#define __deref_out_ecount_full_opt(size) __deref_out_ecount_full(size) __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_out_bcount_full_opt
-#define __deref_out_bcount_full_opt(size) __deref_out_bcount_full(size) __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_inout_opt
-#define __deref_inout_opt __deref_inout __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_inout_ecount_opt
-#define __deref_inout_ecount_opt(size) __deref_inout_ecount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_inout_bcount_opt
-#define __deref_inout_bcount_opt(size) __deref_inout_bcount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_inout_ecount_part_opt
-#define __deref_inout_ecount_part_opt(size,length) __deref_inout_ecount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_inout_bcount_part_opt
-#define __deref_inout_bcount_part_opt(size,length) __deref_inout_bcount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_inout_ecount_full_opt
-#define __deref_inout_ecount_full_opt(size) __deref_inout_ecount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#endif
-#ifndef __deref_inout_bcount_full_opt
-#define __deref_inout_bcount_full_opt(size) __deref_inout_bcount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
-#endif
-
-#ifndef __deref_opt_ecount
-#define __deref_opt_ecount(size) __deref_ecount(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_bcount
-#define __deref_opt_bcount(size) __deref_bcount(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_in
-#define __deref_opt_in __deref_in __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_in_ecount
-#define __deref_opt_in_ecount(size) __deref_in_ecount(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_in_bcount
-#define __deref_opt_in_bcount(size) __deref_in_bcount(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out
-#define __deref_opt_out __deref_out __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_ecount
-#define __deref_opt_out_ecount(size) __deref_out_ecount(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_bcount
-#define __deref_opt_out_bcount(size) __deref_out_bcount(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_ecount_part
-#define __deref_opt_out_ecount_part(size,length) __deref_out_ecount_part(size,length) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_bcount_part
-#define __deref_opt_out_bcount_part(size,length) __deref_out_bcount_part(size,length) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_ecount_full
-#define __deref_opt_out_ecount_full(size) __deref_out_ecount_full(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_bcount_full
-#define __deref_opt_out_bcount_full(size) __deref_out_bcount_full(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout
-#define __deref_opt_inout __deref_inout __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_ecount
-#define __deref_opt_inout_ecount(size) __deref_inout_ecount(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_bcount
-#define __deref_opt_inout_bcount(size) __deref_inout_bcount(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_ecount_part
-#define __deref_opt_inout_ecount_part(size,length) __deref_inout_ecount_part(size,length) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_bcount_part
-#define __deref_opt_inout_bcount_part(size,length) __deref_inout_bcount_part(size,length) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_ecount_full
-#define __deref_opt_inout_ecount_full(size) __deref_inout_ecount_full(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_bcount_full
-#define __deref_opt_inout_bcount_full(size) __deref_inout_bcount_full(size) __exceptthat __maybenull
-#endif
-
-#ifndef __deref_opt_ecount_opt
-#define __deref_opt_ecount_opt(size) __deref_ecount_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_bcount_opt
-#define __deref_opt_bcount_opt(size) __deref_bcount_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_in_opt
-#define __deref_opt_in_opt __deref_in_opt __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_in_ecount_opt
-#define __deref_opt_in_ecount_opt(size) __deref_in_ecount_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_in_bcount_opt
-#define __deref_opt_in_bcount_opt(size) __deref_in_bcount_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_opt
-#define __deref_opt_out_opt __deref_out_opt __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_ecount_opt
-#define __deref_opt_out_ecount_opt(size) __deref_out_ecount_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_bcount_opt
-#define __deref_opt_out_bcount_opt(size) __deref_out_bcount_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_ecount_part_opt
-#define __deref_opt_out_ecount_part_opt(size,length) __deref_out_ecount_part_opt(size,length) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_bcount_part_opt
-#define __deref_opt_out_bcount_part_opt(size,length) __deref_out_bcount_part_opt(size,length) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_ecount_full_opt
-#define __deref_opt_out_ecount_full_opt(size) __deref_out_ecount_full_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_out_bcount_full_opt
-#define __deref_opt_out_bcount_full_opt(size) __deref_out_bcount_full_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_opt
-#define __deref_opt_inout_opt __deref_inout_opt __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_ecount_opt
-#define __deref_opt_inout_ecount_opt(size) __deref_inout_ecount_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_bcount_opt
-#define __deref_opt_inout_bcount_opt(size) __deref_inout_bcount_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_ecount_part_opt
-#define __deref_opt_inout_ecount_part_opt(size,length) __deref_inout_ecount_part_opt(size,length) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_bcount_part_opt
-#define __deref_opt_inout_bcount_part_opt(size,length) __deref_inout_bcount_part_opt(size,length) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_ecount_full_opt
-#define __deref_opt_inout_ecount_full_opt(size) __deref_inout_ecount_full_opt(size) __exceptthat __maybenull
-#endif
-#ifndef __deref_opt_inout_bcount_full_opt
-#define __deref_opt_inout_bcount_full_opt(size) __deref_inout_bcount_full_opt(size) __exceptthat __maybenull
-#endif
-
-// @@BEGIN_DDKSPLIT
-// -------------------------------------------------------------------------------
-// Advanced Annotation Definitions
-//
-// Any of these may be used to directly annotate functions, and may be used in
-// combination with each other or with regular buffer macros. For an explanation
-// of each annotation, see the advanced annotations section.
-// -------------------------------------------------------------------------------
-// @@END_DDKSPLIT
-
-#ifndef __out_awcount
-#define __out_awcount(expr,size) __pre __notnull \
- __precond(expr) __byte_writableTo(size) \
- __precond(!(expr)) __byte_writableTo((size)*2) \
- __post __valid __refparam
-#endif
-#ifndef __in_awcount
-#define __in_awcount(expr,size) __pre __valid \
- __pre __deref __readonly \
- __precond(expr) __byte_readableTo(size) \
- __precond(!(expr)) __elem_readableTo(size)
-#endif
-#ifndef __success
-#define __success(expr) __inner_success(expr)
-#endif
-#ifndef __nullterminated
-#define __nullterminated __readableTo(sentinel(0))
-#endif
-#ifndef __nullnullterminated
-#define __nullnullterminated
-#endif
-#ifndef __reserved
-#define __reserved __pre __null
-#endif
-#ifndef __checkReturn
-#define __checkReturn __inner_checkReturn
-#endif
-#ifndef __typefix
-#define __typefix(ctype) __inner_typefix(ctype)
-#endif
-#ifndef __override
-#define __override __inner_override
-#endif
-#ifndef __callback
-#define __callback __inner_callback
-#endif
-#ifndef __format_string
-#define __format_string
-#endif
-#ifndef __blocksOn
-#define __blocksOn(resource) __inner_blocksOn(resource)
-#endif
-#ifndef __control_entrypoint
-#define __control_entrypoint(category) __inner_control_entrypoint(category)
-#endif
-#ifndef __data_entrypoint
-#define __data_entrypoint(category) __inner_data_entrypoint(category)
-#endif
-
-#ifndef __fallthrough
- __inner_fallthrough_dec
- #define __fallthrough __inner_fallthrough
-#endif
-
-// -------------------------------------------------------------------------------
-// Deprecated Annotation Definitions
-//
-// These should be removed from existing code.
-// -------------------------------------------------------------------------------
-
-// #define __opt __exceptthat __maybenull
-
-#ifdef __cplusplus
-}
-#endif
-
+/***************************************************************\
+* *
+* SpecStrings.h - markers for documenting the semantics of APIs *
+* *
+* Version 1.0 *
+* *
+* Copyright (c) Microsoft Corporation. All rights reserved. *
+* *
+\***************************************************************/
+
+// @@BEGIN_DDKSPLIT
+
+// -------------------------------------------------------------------------------
+// Introduction
+//
+// SpecStrings.h provides a set of annotations to describe how a function uses its
+// parameters - the assumptions it makes about them, and the guarantees it makes
+// upon finishing.
+//
+// Annotations may be placed before either a function parameter's type or its return
+// type, and describe the function's behavior regarding the parameter or return value.
+// There are two classes of annotations: buffer annotations and advanced annotations.
+// Buffer annotations describe how functions use their pointer parameters, and
+// advanced annotations either describe complex/unusual buffer behavior, or provide
+// additional information about a parameter that is not otherwise expressible.
+//
+// -------------------------------------------------------------------------------
+// Buffer Annotations
+//
+// The most important annotations in SpecStrings.h provide a consistent way to annotate
+// buffer parameters or return values for a function. Each of these annotations describes
+// a single buffer (which could be a string, a fixed-length or variable-length array,
+// or just a pointer) that the function interacts with: where it is, how large it is,
+// how much is initialized, and what the function does with it.
+//
+// The appropriate macro for a given buffer can be constructed using the table below.
+// Just pick the appropriate values from each category, and combine them together
+// with a leading underscore. Some combinations of values do not make sense as buffer
+// annotations. Only meaningful annotations can be added to your code; for a list of
+// these, see the buffer annotation definitions section.
+//
+// Only a single buffer annotation should be used for each parameter.
+//
+// |------------|------------|---------|--------|----------|---------------|
+// | Level | Usage | Size | Output | Optional | Parameters |
+// |------------|------------|---------|--------|----------|---------------|
+// | <> | <> | <> | <> | <> | <> |
+// | _deref | _in | _ecount | _full | _opt | (size) |
+// | _deref_opt | _out | _bcount | _part | | (size,length) |
+// | | _inout | | | | |
+// | | | | | | |
+// |------------|------------|---------|--------|----------|---------------|
+//
+// Level: Describes the buffer pointer's level of indirection from the parameter or
+// return value 'p'.
+//
+// <> : p is the buffer pointer.
+// _deref : *p is the buffer pointer. p must not be NULL.
+// _deref_opt : *p may be the buffer pointer. p may be NULL, in which case the rest of
+// the annotation is ignored.
+//
+// Usage: Describes how the function uses the buffer.
+//
+// <> : The buffer is not accessed. If used on the return value or with _deref, the
+// function will provide the buffer, and it will be uninitialized at exit.
+// Otherwise, the caller must provide the buffer. This should only be used
+// for alloc and free functions.
+// _in : The function will only read from the buffer. The caller must provide the
+// buffer and initialize it.
+// _out : The function will only write to the buffer. If used on the return value or
+// with _deref, the function will provide the buffer and initialize it.
+// Otherwise, the caller must provide the buffer, and the function will
+// initialize it.
+// _inout : The function may freely read from and write to the buffer. The caller must
+// provide the buffer and initialize it. If used with _deref, the buffer may
+// be reallocated by the function.
+//
+// Size: Describes the total size of the buffer. This may be less than the space actually
+// allocated for the buffer, in which case it describes the accessible amount.
+//
+// <> : No buffer size is given. If the type specifies the buffer size (such as
+// with LPSTR and LPWSTR), that amount is used. Otherwise, the buffer is one
+// element long. Must be used with _in, _out, or _inout.
+// _ecount : The buffer size is an explicit element count.
+// _bcount : The buffer size is an explicit byte count.
+//
+// Output: Describes how much of the buffer will be initialized by the function. For
+// _inout buffers, this also describes how much is initialized at entry. Omit this
+// category for _in buffers; they must be fully initialized by the caller.
+//
+// <> : The type specifies how much is initialized. For instance, a function initializing
+// an LPWSTR must NULL-terminate the string.
+// _full : The function initializes the entire buffer.
+// _part : The function initializes part of the buffer, and explicitly indicates how much.
+//
+// Optional: Describes if the buffer itself is optional.
+//
+// <> : The pointer to the buffer must not be NULL.
+// _opt : The pointer to the buffer might be NULL. It will be checked before being dereferenced.
+//
+// Parameters: Gives explicit counts for the size and length of the buffer.
+//
+// <> : There is no explicit count. Use when neither _ecount nor _bcount is used.
+// (size) : Only the buffer's total size is given. Use with _ecount or _bcount but not _part.
+// (size,length) : The buffer's total size and initialized length are given. Use with _ecount_part
+// and _bcount_part.
+//
+// -------------------------------------------------------------------------------
+// Buffer Annotation Examples
+//
+// LWSTDAPI_(BOOL) StrToIntExA(
+// LPCSTR pszString, // No annotation required, const implies __in.
+// DWORD dwFlags,
+// __out int *piRet // A pointer whose dereference will be filled in.
+// );
+//
+// void MyPaintingFunction(
+// __in HWND hwndControl, // An initialized read-only parameter.
+// __in_opt HDC hdcOptional, // An initialized read-only parameter that might be NULL.
+// __inout IPropertyStore *ppsStore // An initialized parameter that may be freely used
+// // and modified.
+// );
+//
+// LWSTDAPI_(BOOL) PathCompactPathExA(
+// __out_ecount(cchMax) LPSTR pszOut, // A string buffer with cch elements that will
+// // be NULL terminated on exit.
+// LPCSTR pszSrc, // No annotation required, const implies __in.
+// UINT cchMax,
+// DWORD dwFlags
+// );
+//
+// HRESULT SHLocalAllocBytes(
+// size_t cb,
+// __deref_bcount(cb) T **ppv // A pointer whose dereference will be set to an
+// // uninitialized buffer with cb bytes.
+// );
+//
+// __inout_bcount_full(cb) : A buffer with cb elements that is fully initialized at
+// entry and exit, and may be written to by this function.
+//
+// __out_ecount_part(count, *countOut) : A buffer with count elements that will be
+// partially initialized by this function. The function indicates how much it
+// initialized by setting *countOut.
+//
+// -------------------------------------------------------------------------------
+// Advanced Annotations
+//
+// Advanced annotations describe behavior that is not expressible with the regular
+// buffer macros. These may be used either to annotate buffer parameters that involve
+// complex or conditional behavior, or to enrich existing annotations with additional
+// information.
+//
+// __success(expr) f :
+// <expr> indicates whether function f succeeded or not. If <expr> is true at exit,
+// all the function's guarantees (as given by other annotations) must hold. If <expr>
+// is false at exit, the caller should not expect any of the function's guarantees
+// to hold. If not used, the function must always satisfy its guarantees. Added
+// automatically to functions that indicate success in standard ways, such as by
+// returning an HRESULT.
+//
+// __out_awcount(expr, size) p :
+// Pointer p is a buffer whose size may be given in either bytes or elements. If
+// <expr> is true, this acts like __out_bcount. If <expr> is false, this acts
+// like __out_ecount. This should only be used to annotate old APIs.
+//
+// __in_awcount(expr, size) p :
+// Pointer p is a buffer whose size may be given in either bytes or elements. If
+// <expr> is true, this acts like __in_bcount. If <expr> is false, this acts
+// like __in_ecount. This should only be used to annotate old APIs.
+//
+// __nullterminated p :
+// Pointer p is a buffer that may be read or written up to and including the first
+// NULL character or pointer. May be used on typedefs, which marks valid (properly
+// initialized) instances of that type as being NULL-terminated.
+//
+// __nullnullterminated p :
+// Pointer p is a buffer that may be read or written up to and including the first
+// sequence of two NULL characters or pointers. May be used on typedefs, which marks
+// valid instances of that type as being double-NULL terminated.
+//
+// __reserved v :
+// Value v must be 0/NULL, reserved for future use.
+//
+// __checkReturn v :
+// Return value v must not be ignored by callers of this function.
+//
+// __typefix(ctype) v :
+// Value v should be treated as an instance of ctype, rather than its declared type.
+//
+// __override f :
+// Specify C#-style 'override' behaviour for overriding virtual methods.
+//
+// __callback f :
+// Function f can be used as a function pointer.
+//
+// __format_string p :
+// Pointer p is a string that contains % markers in the style of printf.
+//
+// __blocksOn(resource) f :
+// Function f blocks on the resource 'resource'.
+//
+// __fallthrough :
+// Annotates switch statement labels where fall-through is desired, to distinguish
+// from forgotten break statements.
+//
+// -------------------------------------------------------------------------------
+// Advanced Annotation Examples
+//
+// __success(return == TRUE) LWSTDAPI_(BOOL)
+// PathCanonicalizeA(__out_ecount(MAX_PATH) LPSTR pszBuf, LPCSTR pszPath) :
+// pszBuf is only guaranteed to be NULL-terminated when TRUE is returned.
+//
+// typedef __nullterminated WCHAR* LPWSTR : Initialized LPWSTRs are NULL-terminated strings.
+//
+// __out_ecount(cch) __typefix(LPWSTR) void *psz : psz is a buffer parameter which will be
+// a NULL-terminated WCHAR string at exit, and which initially contains cch WCHARs.
+//
+// -------------------------------------------------------------------------------
+
+// @@END_DDKSPLIT
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // #if _MSC_VER > 1000
+
+#define __specstrings
+
+#ifdef __cplusplus
+#ifndef __nothrow
+# define __nothrow __declspec(nothrow)
+#endif
+extern "C" {
+#else
+#ifndef __nothrow
+# define __nothrow
+#endif
+#endif // #ifdef __cplusplus
+
+// @@BEGIN_DDKSPLIT
+
+// -------------------------------------------------------------------------------
+// Helper Macro Definitions
+//
+// These express behavior common to many of the high-level annotations.
+// DO NOT USE THESE IN YOUR CODE.
+// -------------------------------------------------------------------------------
+
+// The helper annotations are only understood by the compiler version used by various
+// defect detection tools. When the regular compiler is running, they are defined into
+// nothing, and do not affect the compiled code.
+#if (_MSC_VER >= 1000) && !defined(MIDL_PASS) && defined(_PREFAST_)
+
+ // In the primitive __declspec("SAL_*") annotations "SAL" stands for Standard
+ // Annotation Language. These __declspec("SAL_*") annotations are the
+ // primitives the compiler understands and all high-level SpecString MACROs
+ // will decompose into these primivates.
+
+ #define SPECSTRINGIZE( x ) #x
+
+ //
+ // __null p
+ // __notnull p
+ // __maybenull p
+ //
+ // Annotates a pointer p. States that pointer p is null. Commonly used
+ // in the negated form __notnull or the possibly null form __maybenull.
+ //
+ #define __null __declspec("SAL_null")
+ #define __notnull __declspec("SAL_notnull")
+ #define __maybenull __declspec("SAL_maybenull")
+
+ //
+ // __readonly l
+ // __notreadonly l
+ // __mabyereadonly l
+ //
+ // Annotates a location l. States that location l is not modified after
+ // this point. If the annotation is placed on the precondition state of
+ // a function, the restriction only applies until the postcondition state
+ // of the function. __maybereadonly states that the annotated location
+ // may be modified, whereas __notreadonly states that a location must be
+ // modified.
+ //
+ #define __readonly __declspec("SAL_readonly")
+ #define __notreadonly __declspec("SAL_notreadonly")
+ #define __maybereadonly __declspec("SAL_maybereadonly")
+
+ //
+ // __valid v
+ // __notvalid v
+ // __maybevalid v
+ //
+ // Annotates any value v. States that the value satisfies all properties of
+ // valid values of its type. For example, for a string buffer, valid means
+ // that the buffer pointer is either NULL or points to a NULL-terminated string.
+ //
+ #define __valid __declspec("SAL_valid")
+ #define __notvalid __declspec("SAL_notvalid")
+ #define __maybevalid __declspec("SAL_maybevalid")
+
+ //
+ // __readableTo(extent) p
+ //
+ // Annotates a buffer pointer p. If the buffer can be read, extent describes
+ // how much of the buffer is readable. For a reader of the buffer, this is
+ // an explicit permission to read up to that amount, rather than a restriction to
+ // read only up to it.
+ //
+ #define __readableTo(extent) __declspec("SAL_readableTo("SPECSTRINGIZE(extent)")")
+
+ //
+ // __elem_readableTo(size)
+ //
+ // Annotates a buffer pointer p as being readable to size elements.
+ //
+ #define __elem_readableTo(size) __declspec("SAL_readableTo(elementCount("SPECSTRINGIZE(size)"))")
+
+ //
+ // __byte_readableTo(size)
+ //
+ // Annotates a buffer pointer p as being readable to size bytes.
+ //
+ #define __byte_readableTo(size) __declspec("SAL_readableTo(byteCount("SPECSTRINGIZE(size)"))")
+
+ //
+ // __writableTo(extent) p
+ //
+ // Annotates a buffer pointer p. If the buffer can be modified, extent
+ // describes how much of the buffer is writable (usually the allocation
+ // size). For a writer of the buffer, this is an explicit permission to
+ // write up to that amount, rather than a restriction to write only up to it.
+ //
+ #define __writableTo(size) __declspec("SAL_writableTo("SPECSTRINGIZE(size)")")
+
+ //
+ // __elem_writableTo(size)
+ //
+ // Annotates a buffer pointer p as being writable to size elements.
+ //
+ #define __elem_writableTo(size) __declspec("SAL_writableTo(elementCount("SPECSTRINGIZE(size)"))")
+
+ //
+ // __byte_writableTo(size)
+ //
+ // Annotates a buffer pointer p as being writable to size bytes.
+ //
+ #define __byte_writableTo(size) __declspec("SAL_writableTo(byteCount("SPECSTRINGIZE(size)"))")
+
+ //
+ // __deref p
+ //
+ // Annotates a pointer p. The next annotation applies one dereference down
+ // in the type. If readableTo(p, size) then the next annotation applies to
+ // all elements *(p+i) for which i satisfies the size. If p is a pointer
+ // to a struct, the next annotation applies to all fields of the struct.
+ //
+ #define __deref __declspec("SAL_deref")
+
+ //
+ // __pre __next_annotation
+ //
+ // The next annotation applies in the precondition state
+ //
+ #define __pre __declspec("SAL_pre")
+
+ //
+ // __post __next_annotation
+ //
+ // The next annotation applies in the postcondition state
+ //
+ #define __post __declspec("SAL_post")
+
+ //
+ // __precond(<expr>)
+ //
+ // When <expr> is true, the next annotation applies in the precondition state
+ // (currently not enabled)
+ //
+ #define __precond(expr) __pre
+
+ //
+ // __postcond(<expr>)
+ //
+ // When <expr> is true, the next annotation applies in the postcondition state
+ // (currently not enabled)
+ //
+ #define __postcond(expr) __post
+
+ //
+ // __exceptthat
+ //
+ // Given a set of annotations Q containing __exceptthat maybeP, the effect of
+ // the except clause is to erase any P or notP annotations (explicit or
+ // implied) within Q at the same level of dereferencing that the except
+ // clause appears, and to replace it with maybeP.
+ //
+ // Example 1: __valid __exceptthat __maybenull on a pointer p means that the
+ // pointer may be null, and is otherwise valid, thus overriding
+ // the implicit notnull annotation implied by __valid on
+ // pointers.
+ //
+ // Example 2: __valid __deref __exceptthat __maybenull on an int **p means
+ // that p is not null (implied by valid), but the elements
+ // pointed to by p could be null, and are otherwise valid.
+ //
+ #define __exceptthat __declspec("SAL_except")
+
+ //
+ // _refparam
+ //
+ // Added to all out parameter macros to indicate that they are all reference
+ // parameters.
+ //
+ #define __refparam __deref __notreadonly
+
+ //
+ // __inner_*
+ //
+ // Helper macros that directly correspond to certain high-level annotations.
+ //
+ //
+
+ // Macros to classify the entrypoints and indicate their category.
+ //
+ //
+ // Pre-defined control point categories include: RPC, LPC, DeviceDriver, UserToKernel, ISAPI, COM.
+ //
+ #define __inner_control_entrypoint(category) __declspec("SAL_entrypoint(controlEntry, "SPECSTRINGIZE(category)")")
+
+ //
+ // Pre-defined data entry point categories include: Registry, File, Network.
+ //
+ #define __inner_data_entrypoint(category) __declspec("SAL_entrypoint(dataEntry, "SPECSTRINGIZE(category)")")
+
+ #define __inner_success(expr) __declspec("SAL_success("SPECSTRINGIZE(expr)")")
+ #define __inner_checkReturn __declspec("SAL_checkReturn")
+ #define __inner_typefix(ctype) __declspec("SAL_typefix("SPECSTRINGIZE(ctype)")")
+ #define __inner_override __declspec("__override")
+ #define __inner_callback __declspec("__callback")
+ #define __inner_blocksOn(resource) __declspec("SAL_blocksOn("SPECSTRINGIZE(resource)")")
+ #define __inner_fallthrough_dec __inline __nothrow void __FallThrough() {}
+ #define __inner_fallthrough __FallThrough();
+
+#else
+
+// @@END_DDKSPLIT
+
+#ifndef __null
+ #define __null
+#endif
+#ifndef __notnull
+ #define __notnull
+#endif
+#ifndef __maybenull
+ #define __maybenull
+#endif
+#ifndef __readonly
+ #define __readonly
+#endif
+#ifndef __notreadonly
+ #define __notreadonly
+#endif
+#ifndef __maybereadonly
+ #define __maybereadonly
+#endif
+#ifndef __valid
+ #define __valid
+#endif
+#ifndef __notvalid
+ #define __notvalid
+#endif
+#ifndef __maybevalid
+ #define __maybevalid
+#endif
+#ifndef __readableTo
+ #define __readableTo(extent)
+#endif
+#ifndef __elem_readableTo
+ #define __elem_readableTo(size)
+#endif
+#ifndef __byte_readableTo
+ #define __byte_readableTo(size)
+#endif
+#ifndef __writableTo
+ #define __writableTo(size)
+#endif
+#ifndef __elem_writableTo
+ #define __elem_writableTo(size)
+#endif
+#ifndef __byte_writableTo
+ #define __byte_writableTo(size)
+#endif
+#ifndef __deref
+ #define __deref
+#endif
+#ifndef __pre
+ #define __pre
+#endif
+#ifndef __post
+ #define __post
+#endif
+#ifndef __precond
+ #define __precond(expr)
+#endif
+#ifndef __postcond
+ #define __postcond(expr)
+#endif
+#ifndef __exceptthat
+ #define __exceptthat
+#endif
+#ifndef __inner_success
+ #define __inner_success(expr)
+#endif
+#ifndef __inner_checkReturn
+ #define __inner_checkReturn
+#endif
+#ifndef __inner_typefix
+ #define __inner_typefix(ctype)
+#endif
+#ifndef __inner_override
+ #define __inner_override
+#endif
+#ifndef __inner_callback
+ #define __inner_callback
+#endif
+#ifndef __inner_blocksOn
+ #define __inner_blocksOn(resource)
+#endif
+#ifndef __inner_fallthrough_dec
+ #define __inner_fallthrough_dec
+#endif
+#ifndef __inner_fallthrough
+ #define __inner_fallthrough
+#endif
+#ifndef __refparam
+ #define __refparam
+#endif
+#ifndef __inner_control_entrypoint
+ #define __inner_control_entrypoint(category)
+#endif
+#ifndef __inner_data_entrypoint
+ #define __inner_data_entrypoint(category)
+#endif
+// @@BEGIN_DDKSPLIT
+#endif // #if (_MSC_VER >= 1000) && !defined(MIDL_PASS) && defined(_PREFAST_)
+// -------------------------------------------------------------------------------
+// Buffer Annotation Definitions
+//
+// Any of these may be used to directly annotate functions, but only one should
+// be used for each parameter. To determine which annotation to use for a given
+// buffer, use the table in the buffer annotations section.
+// -------------------------------------------------------------------------------
+// @@END_DDKSPLIT
+
+#ifndef __ecount
+#define __ecount(size) __notnull __elem_writableTo(size)
+#endif
+#ifndef __bcount
+#define __bcount(size) __notnull __byte_writableTo(size)
+#endif
+#ifndef __in
+#define __in __pre __valid __pre __deref __readonly
+#endif
+#ifndef __in_ecount
+#define __in_ecount(size) __in __pre __elem_readableTo(size)
+#endif
+#ifndef __in_bcount
+#define __in_bcount(size) __in __pre __byte_readableTo(size)
+#endif
+#ifndef __out
+#define __out __ecount(1) __post __valid __refparam
+#endif
+#ifndef __out_ecount
+#define __out_ecount(size) __ecount(size) __post __valid __refparam
+#endif
+#ifndef __out_bcount
+#define __out_bcount(size) __bcount(size) __post __valid __refparam
+#endif
+#ifndef __out_ecount_part
+#define __out_ecount_part(size,length) __out_ecount(size) __post __elem_readableTo(length)
+#endif
+#ifndef __out_bcount_part
+#define __out_bcount_part(size,length) __out_bcount(size) __post __byte_readableTo(length)
+#endif
+#ifndef __out_ecount_full
+#define __out_ecount_full(size) __out_ecount_part(size,size)
+#endif
+#ifndef __out_bcount_full
+#define __out_bcount_full(size) __out_bcount_part(size,size)
+#endif
+#ifndef __inout
+#define __inout __pre __valid __post __valid __refparam
+#endif
+#ifndef __inout_ecount
+#define __inout_ecount(size) __out_ecount(size) __pre __valid
+#endif
+#ifndef __inout_bcount
+#define __inout_bcount(size) __out_bcount(size) __pre __valid
+#endif
+#ifndef __inout_ecount_part
+#define __inout_ecount_part(size,length) __out_ecount_part(size,length) __pre __valid __pre __elem_readableTo(length)
+#endif
+#ifndef __inout_bcount_part
+#define __inout_bcount_part(size,length) __out_bcount_part(size,length) __pre __valid __pre __byte_readableTo(length)
+#endif
+#ifndef __inout_ecount_full
+#define __inout_ecount_full(size) __inout_ecount_part(size,size)
+#endif
+#ifndef __inout_bcount_full
+#define __inout_bcount_full(size) __inout_bcount_part(size,size)
+#endif
+
+#ifndef __ecount_opt
+#define __ecount_opt(size) __ecount(size) __exceptthat __maybenull
+#endif
+#ifndef __bcount_opt
+#define __bcount_opt(size) __bcount(size) __exceptthat __maybenull
+#endif
+#ifndef __in_opt
+#define __in_opt __in __exceptthat __maybenull
+#endif
+#ifndef __in_ecount_opt
+#define __in_ecount_opt(size) __in_ecount(size) __exceptthat __maybenull
+#endif
+#ifndef __in_bcount_opt
+#define __in_bcount_opt(size) __in_bcount(size) __exceptthat __maybenull
+#endif
+#ifndef __out_opt
+#define __out_opt __out __exceptthat __maybenull
+#endif
+#ifndef __out_ecount_opt
+#define __out_ecount_opt(size) __out_ecount(size) __exceptthat __maybenull
+#endif
+#ifndef __out_bcount_opt
+#define __out_bcount_opt(size) __out_bcount(size) __exceptthat __maybenull
+#endif
+#ifndef __out_ecount_part_opt
+#define __out_ecount_part_opt(size,length) __out_ecount_part(size,length) __exceptthat __maybenull
+#endif
+#ifndef __out_bcount_part_opt
+#define __out_bcount_part_opt(size,length) __out_bcount_part(size,length) __exceptthat __maybenull
+#endif
+#ifndef __out_ecount_full_opt
+#define __out_ecount_full_opt(size) __out_ecount_full(size) __exceptthat __maybenull
+#endif
+#ifndef __out_bcount_full_opt
+#define __out_bcount_full_opt(size) __out_bcount_full(size) __exceptthat __maybenull
+#endif
+#ifndef __inout_opt
+#define __inout_opt __inout __exceptthat __maybenull
+#endif
+#ifndef __inout_ecount_opt
+#define __inout_ecount_opt(size) __inout_ecount(size) __exceptthat __maybenull
+#endif
+#ifndef __inout_bcount_opt
+#define __inout_bcount_opt(size) __inout_bcount(size) __exceptthat __maybenull
+#endif
+#ifndef __inout_ecount_part_opt
+#define __inout_ecount_part_opt(size,length) __inout_ecount_part(size,length) __exceptthat __maybenull
+#endif
+#ifndef __inout_bcount_part_opt
+#define __inout_bcount_part_opt(size,length) __inout_bcount_part(size,length) __exceptthat __maybenull
+#endif
+#ifndef __inout_ecount_full_opt
+#define __inout_ecount_full_opt(size) __inout_ecount_full(size) __exceptthat __maybenull
+#endif
+#ifndef __inout_bcount_full_opt
+#define __inout_bcount_full_opt(size) __inout_bcount_full(size) __exceptthat __maybenull
+#endif
+
+#ifndef __deref_ecount
+#define __deref_ecount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __elem_writableTo(size)
+#endif
+#ifndef __deref_bcount
+#define __deref_bcount(size) __ecount(1) __post __elem_readableTo(1) __post __deref __notnull __post __deref __byte_writableTo(size)
+#endif
+#ifndef __deref_in
+#define __deref_in __in __pre __deref __deref __readonly
+#endif
+#ifndef __deref_in_ecount
+#define __deref_in_ecount(size) __deref_in __pre __deref __elem_readableTo(size)
+#endif
+#ifndef __deref_in_bcount
+#define __deref_in_bcount(size) __deref_in __pre __deref __byte_readableTo(size)
+#endif
+#ifndef __deref_out
+#define __deref_out __deref_ecount(1) __post __deref __valid __refparam
+#endif
+#ifndef __deref_out_ecount
+#define __deref_out_ecount(size) __deref_ecount(size) __post __deref __valid __refparam
+#endif
+#ifndef __deref_out_bcount
+#define __deref_out_bcount(size) __deref_bcount(size) __post __deref __valid __refparam
+#endif
+#ifndef __deref_out_ecount_part
+#define __deref_out_ecount_part(size,length) __deref_out_ecount(size) __post __deref __elem_readableTo(length)
+#endif
+#ifndef __deref_out_bcount_part
+#define __deref_out_bcount_part(size,length) __deref_out_bcount(size) __post __deref __byte_readableTo(length)
+#endif
+#ifndef __deref_out_ecount_full
+#define __deref_out_ecount_full(size) __deref_out_ecount_part(size,size)
+#endif
+#ifndef __deref_out_bcount_full
+#define __deref_out_bcount_full(size) __deref_out_bcount_part(size,size)
+#endif
+#ifndef __deref_inout
+#define __deref_inout __notnull __elem_readableTo(1) __pre __deref __valid __post __deref __valid __refparam
+#endif
+#ifndef __deref_inout_ecount
+#define __deref_inout_ecount(size) __deref_inout __pre __deref __elem_writableTo(size) __post __deref __elem_writableTo(size)
+#endif
+#ifndef __deref_inout_bcount
+#define __deref_inout_bcount(size) __deref_inout __pre __deref __byte_writableTo(size) __post __deref __byte_writableTo(size)
+#endif
+#ifndef __deref_inout_ecount_part
+#define __deref_inout_ecount_part(size,length) __deref_inout_ecount(size) __pre __deref __elem_readableTo(length) __post __deref __elem_readableTo(length)
+#endif
+#ifndef __deref_inout_bcount_part
+#define __deref_inout_bcount_part(size,length) __deref_inout_bcount(size) __pre __deref __byte_readableTo(length) __post __deref __byte_readableTo(length)
+#endif
+#ifndef __deref_inout_ecount_full
+#define __deref_inout_ecount_full(size) __deref_inout_ecount_part(size,size)
+#endif
+#ifndef __deref_inout_bcount_full
+#define __deref_inout_bcount_full(size) __deref_inout_bcount_part(size,size)
+#endif
+
+#ifndef __deref_ecount_opt
+#define __deref_ecount_opt(size) __deref_ecount(size) __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_bcount_opt
+#define __deref_bcount_opt(size) __deref_bcount(size) __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_in_opt
+#define __deref_in_opt __deref_in __pre __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_in_ecount_opt
+#define __deref_in_ecount_opt(size) __deref_in_ecount(size) __pre __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_in_bcount_opt
+#define __deref_in_bcount_opt(size) __deref_in_bcount(size) __pre __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_out_opt
+#define __deref_out_opt __deref_out __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_out_ecount_opt
+#define __deref_out_ecount_opt(size) __deref_out_ecount(size) __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_out_bcount_opt
+#define __deref_out_bcount_opt(size) __deref_out_bcount(size) __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_out_ecount_part_opt
+#define __deref_out_ecount_part_opt(size,length) __deref_out_ecount_part(size,length) __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_out_bcount_part_opt
+#define __deref_out_bcount_part_opt(size,length) __deref_out_bcount_part(size,length) __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_out_ecount_full_opt
+#define __deref_out_ecount_full_opt(size) __deref_out_ecount_full(size) __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_out_bcount_full_opt
+#define __deref_out_bcount_full_opt(size) __deref_out_bcount_full(size) __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_inout_opt
+#define __deref_inout_opt __deref_inout __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_inout_ecount_opt
+#define __deref_inout_ecount_opt(size) __deref_inout_ecount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_inout_bcount_opt
+#define __deref_inout_bcount_opt(size) __deref_inout_bcount(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_inout_ecount_part_opt
+#define __deref_inout_ecount_part_opt(size,length) __deref_inout_ecount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_inout_bcount_part_opt
+#define __deref_inout_bcount_part_opt(size,length) __deref_inout_bcount_part(size,length) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_inout_ecount_full_opt
+#define __deref_inout_ecount_full_opt(size) __deref_inout_ecount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#endif
+#ifndef __deref_inout_bcount_full_opt
+#define __deref_inout_bcount_full_opt(size) __deref_inout_bcount_full(size) __pre __deref __exceptthat __maybenull __post __deref __exceptthat __maybenull
+#endif
+
+#ifndef __deref_opt_ecount
+#define __deref_opt_ecount(size) __deref_ecount(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_bcount
+#define __deref_opt_bcount(size) __deref_bcount(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_in
+#define __deref_opt_in __deref_in __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_in_ecount
+#define __deref_opt_in_ecount(size) __deref_in_ecount(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_in_bcount
+#define __deref_opt_in_bcount(size) __deref_in_bcount(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out
+#define __deref_opt_out __deref_out __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_ecount
+#define __deref_opt_out_ecount(size) __deref_out_ecount(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_bcount
+#define __deref_opt_out_bcount(size) __deref_out_bcount(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_ecount_part
+#define __deref_opt_out_ecount_part(size,length) __deref_out_ecount_part(size,length) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_bcount_part
+#define __deref_opt_out_bcount_part(size,length) __deref_out_bcount_part(size,length) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_ecount_full
+#define __deref_opt_out_ecount_full(size) __deref_out_ecount_full(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_bcount_full
+#define __deref_opt_out_bcount_full(size) __deref_out_bcount_full(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout
+#define __deref_opt_inout __deref_inout __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_ecount
+#define __deref_opt_inout_ecount(size) __deref_inout_ecount(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_bcount
+#define __deref_opt_inout_bcount(size) __deref_inout_bcount(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_ecount_part
+#define __deref_opt_inout_ecount_part(size,length) __deref_inout_ecount_part(size,length) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_bcount_part
+#define __deref_opt_inout_bcount_part(size,length) __deref_inout_bcount_part(size,length) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_ecount_full
+#define __deref_opt_inout_ecount_full(size) __deref_inout_ecount_full(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_bcount_full
+#define __deref_opt_inout_bcount_full(size) __deref_inout_bcount_full(size) __exceptthat __maybenull
+#endif
+
+#ifndef __deref_opt_ecount_opt
+#define __deref_opt_ecount_opt(size) __deref_ecount_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_bcount_opt
+#define __deref_opt_bcount_opt(size) __deref_bcount_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_in_opt
+#define __deref_opt_in_opt __deref_in_opt __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_in_ecount_opt
+#define __deref_opt_in_ecount_opt(size) __deref_in_ecount_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_in_bcount_opt
+#define __deref_opt_in_bcount_opt(size) __deref_in_bcount_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_opt
+#define __deref_opt_out_opt __deref_out_opt __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_ecount_opt
+#define __deref_opt_out_ecount_opt(size) __deref_out_ecount_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_bcount_opt
+#define __deref_opt_out_bcount_opt(size) __deref_out_bcount_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_ecount_part_opt
+#define __deref_opt_out_ecount_part_opt(size,length) __deref_out_ecount_part_opt(size,length) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_bcount_part_opt
+#define __deref_opt_out_bcount_part_opt(size,length) __deref_out_bcount_part_opt(size,length) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_ecount_full_opt
+#define __deref_opt_out_ecount_full_opt(size) __deref_out_ecount_full_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_out_bcount_full_opt
+#define __deref_opt_out_bcount_full_opt(size) __deref_out_bcount_full_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_opt
+#define __deref_opt_inout_opt __deref_inout_opt __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_ecount_opt
+#define __deref_opt_inout_ecount_opt(size) __deref_inout_ecount_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_bcount_opt
+#define __deref_opt_inout_bcount_opt(size) __deref_inout_bcount_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_ecount_part_opt
+#define __deref_opt_inout_ecount_part_opt(size,length) __deref_inout_ecount_part_opt(size,length) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_bcount_part_opt
+#define __deref_opt_inout_bcount_part_opt(size,length) __deref_inout_bcount_part_opt(size,length) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_ecount_full_opt
+#define __deref_opt_inout_ecount_full_opt(size) __deref_inout_ecount_full_opt(size) __exceptthat __maybenull
+#endif
+#ifndef __deref_opt_inout_bcount_full_opt
+#define __deref_opt_inout_bcount_full_opt(size) __deref_inout_bcount_full_opt(size) __exceptthat __maybenull
+#endif
+
+// @@BEGIN_DDKSPLIT
+// -------------------------------------------------------------------------------
+// Advanced Annotation Definitions
+//
+// Any of these may be used to directly annotate functions, and may be used in
+// combination with each other or with regular buffer macros. For an explanation
+// of each annotation, see the advanced annotations section.
+// -------------------------------------------------------------------------------
+// @@END_DDKSPLIT
+
+#ifndef __out_awcount
+#define __out_awcount(expr,size) __pre __notnull \
+ __precond(expr) __byte_writableTo(size) \
+ __precond(!(expr)) __byte_writableTo((size)*2) \
+ __post __valid __refparam
+#endif
+#ifndef __in_awcount
+#define __in_awcount(expr,size) __pre __valid \
+ __pre __deref __readonly \
+ __precond(expr) __byte_readableTo(size) \
+ __precond(!(expr)) __elem_readableTo(size)
+#endif
+#ifndef __success
+#define __success(expr) __inner_success(expr)
+#endif
+#ifndef __nullterminated
+#define __nullterminated __readableTo(sentinel(0))
+#endif
+#ifndef __nullnullterminated
+#define __nullnullterminated
+#endif
+#ifndef __reserved
+#define __reserved __pre __null
+#endif
+#ifndef __checkReturn
+#define __checkReturn __inner_checkReturn
+#endif
+#ifndef __typefix
+#define __typefix(ctype) __inner_typefix(ctype)
+#endif
+#ifndef __override
+#define __override __inner_override
+#endif
+#ifndef __callback
+#define __callback __inner_callback
+#endif
+#ifndef __format_string
+#define __format_string
+#endif
+#ifndef __blocksOn
+#define __blocksOn(resource) __inner_blocksOn(resource)
+#endif
+#ifndef __control_entrypoint
+#define __control_entrypoint(category) __inner_control_entrypoint(category)
+#endif
+#ifndef __data_entrypoint
+#define __data_entrypoint(category) __inner_data_entrypoint(category)
+#endif
+
+#ifndef __fallthrough
+ __inner_fallthrough_dec
+ #define __fallthrough __inner_fallthrough
+#endif
+
+// -------------------------------------------------------------------------------
+// Deprecated Annotation Definitions
+//
+// These should be removed from existing code.
+// -------------------------------------------------------------------------------
+
+// #define __opt __exceptthat __maybenull
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/core/src/fxge/apple/apple_int.h b/core/src/fxge/apple/apple_int.h
index 5c42f1b1fb..42d63628f2 100644
--- a/core/src/fxge/apple/apple_int.h
+++ b/core/src/fxge/apple/apple_int.h
@@ -1,246 +1,246 @@
-// 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 _APPLE_INT_H_
-#define _APPLE_INT_H_
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-#if _FX_OS_ == _FX_MACOSX_
-#include <Carbon/Carbon.h>
-#endif
-typedef enum eFXIOSFONTCHARSET {
- eFXFontCharsetDEFAULT = 0,
- eFXFontCharsetANSI = 1,
- eFXFontCharsetSYMBOL = 1 << 1,
- eFXFontCharsetSHIFTJIS = 1 << 2,
- eFXFontCharsetHANGEUL = 1 << 3,
- eFXFontCharsetGB2312 = 1 << 4,
- eFXFontCharsetCHINESEBIG5 = 1 << 5,
- eFXFontCharsetTHAI = 1 << 6,
- eFXFontCharsetEASTEUROPE = 1 << 7,
- eFXFontCharsetRUSSIAN = 1 << 8,
- eFXFontCharsetGREEK = 1 << 9,
- eFXFontCharsetTURKISH = 1 << 10,
- eFXFontCharsetHEBREW = 1 << 11,
- eFXFontCharsetARABIC = 1 << 12,
- eFXFontCharsetBALTIC = 1 << 13,
-} FX_IOSCHARSET;
-FX_IOSCHARSET FX_GetiOSCharset(int charset);
-typedef enum eFXIOSFONTFLAG {
- eFXFontFlagBold = 1,
- eFXFontFlagItalic = 1 << 1,
- eFXFontFlagFixedPitch = 1 << 2,
- eFXFontFlagSerif = 1 << 3,
- eFXFontFlagScript = 1 << 4,
-} FX_IOSFONTFLAG;
-typedef struct _IOS_FONTDATA {
- FX_DWORD nHashCode;
- const char* psName;
- FX_DWORD charsets;
- FX_DWORD styles;
-} IOS_FONTDATA;
-class CQuartz2D
-{
-public:
- void* createGraphics(CFX_DIBitmap* bitmap);
- void destroyGraphics(void* graphics);
-
- void* CreateFont(FX_LPCBYTE pFontData, FX_DWORD dwFontSize);
- void DestroyFont(void* pFont);
- void setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix);
- FX_BOOL drawGraphicsString(void* graphics,
- void* font,
- FX_FLOAT fontSize,
- FX_WORD* glyphIndices,
- CGPoint* glyphPositions,
- FX_INT32 chars,
- FX_ARGB argb,
- CFX_AffineMatrix* matrix = NULL);
- void saveGraphicsState(void* graphics);
- void restoreGraphicsState(void* graphics);
-};
-class CApplePlatform : public CFX_Object
-{
-public:
- CApplePlatform()
- {
- m_pFontMapper = NULL;
- }
- ~CApplePlatform()
- {
- if (m_pFontMapper) {
- delete m_pFontMapper;
- }
- }
- CQuartz2D _quartz2d;
- IFX_FontMapper* m_pFontMapper;
-};
-class CFX_QuartzDeviceDriver : public IFX_RenderDeviceDriver
-{
-public:
- CFX_QuartzDeviceDriver(CGContextRef context, FX_INT32 deviceClass);
- virtual ~CFX_QuartzDeviceDriver();
-
- virtual int GetDeviceCaps(int caps_id);
- virtual CFX_Matrix GetCTM() const;
- virtual CFX_DIBitmap* GetBackDrop()
- {
- return NULL;
- }
- virtual void* GetPlatformSurface()
- {
- return NULL;
- }
- virtual FX_BOOL IsPSPrintDriver()
- {
- return FALSE;
- }
- virtual FX_BOOL StartRendering()
- {
- return TRUE;
- }
- virtual void EndRendering() {}
- virtual void SaveState();
- virtual void RestoreState(FX_BOOL bKeepSaved);
- virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- int fill_mode
- );
- virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState
- );
- virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color,
- FX_DWORD stroke_color,
- int fill_mode,
- int alpha_flag = 0,
- void* pIccTransform = NULL,
- int blend_type = FXDIB_BLEND_NORMAL
- );
- virtual FX_BOOL SetPixel(int x, int y, FX_DWORD color,
- int alpha_flag = 0, void* pIccTransform = NULL)
- {
- return FALSE;
- }
- virtual FX_BOOL FillRect(const FX_RECT* pRect, FX_DWORD fill_color,
- int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
- virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
- int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
- virtual FX_BOOL GetClipBox(FX_RECT* pRect);
- virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE);
- virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect,
- int dest_left, int dest_top, int blend_type,
- int alpha_flag = 0, void* pIccTransform = NULL);
- virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
- virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD flags, FX_LPVOID& handle,
- int alpha_flag = 0, void* pIccTransform = NULL,
- int blend_type = FXDIB_BLEND_NORMAL)
- {
- return FALSE;
- }
- virtual FX_BOOL ContinueDIBits(FX_LPVOID handle, IFX_Pause* pPause)
- {
- return FALSE;
- }
- virtual void CancelDIBits(FX_LPVOID handle) {}
- virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
- CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
- int alpha_flag = 0, void* pIccTransform = NULL);
- virtual void ClearDriver();
-protected:
- void setStrokeInfo(const CFX_GraphStateData * graphState, FX_ARGB argb, FX_FLOAT lineWidth);
- void setFillInfo(FX_ARGB argb);
- void setPathToContext(const CFX_PathData * pathData);
- FX_FLOAT getLineWidth(const CFX_GraphStateData * graphState, CGAffineTransform ctm);
- FX_BOOL CG_DrawGlypRun(int nChars,
- const FXTEXT_CHARPOS* pCharPos,
- CFX_Font* pFont,
- CFX_FontCache* pCache,
- const CFX_AffineMatrix* pGlyphMatrix,
- const CFX_AffineMatrix* pObject2Device,
- FX_FLOAT font_size,
- FX_DWORD argb,
- int alpha_flag,
- void* pIccTransform);
- void CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height, CGRect* rect = NULL);
-protected:
- CGContextRef _context;
- CGAffineTransform _foxitDevice2User;
- CGAffineTransform _user2FoxitDevice;
- FX_INT32 m_saveCount;
-
- FX_INT32 _width;
- FX_INT32 _height;
- FX_INT32 _bitsPerPixel;
- FX_INT32 _deviceClass;
- FX_INT32 _renderCaps;
- FX_INT32 _horzSize;
- FX_INT32 _vertSize;
-};
-class CFX_FontProvider : public IFX_FileRead
-{
-public:
- virtual void Release()
- {
- delete this;
- }
- virtual FX_FILESIZE GetSize()
- {
- return (FX_FILESIZE)_totalSize;
- }
- virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
-
- virtual FX_BOOL IsEOF()
- {
- return _offSet == _totalSize;
- }
- virtual FX_FILESIZE GetPosition()
- {
- return (FX_FILESIZE)_offSet;
- }
- virtual size_t ReadBlock(void* buffer, size_t size);
-public:
- CFX_FontProvider(CGFontRef cgFont);
- ~CFX_FontProvider();
- void InitTableOffset();
- unsigned long Read(unsigned long offset, unsigned char *buffer, unsigned long count);
-protected:
- uint32_t CalcTableCheckSum(const uint32_t *table, uint32_t numberOfBytesInTable);
- uint32_t CalcTableDataRefCheckSum(CFDataRef dataRef);
-private:
- CGFontRef m_cgFont;
- UInt32 m_iTableSize;
- size_t _offSet;
- typedef struct FontHeader {
- int32_t fVersion;
- uint16_t fNumTables;
- uint16_t fSearchRange;
- uint16_t fEntrySelector;
- uint16_t fRangeShift;
- } FontHeader;
- typedef struct TableEntry {
- uint32_t fTag;
- uint32_t fCheckSum;
- uint32_t fOffset;
- uint32_t fLength;
- } TableEntry;
- FontHeader _fontHeader;
- unsigned char * _tableEntries;
- size_t * _tableOffsets;
- int _tableCount;
- int _totalSize;
-};
-FX_UINT32 FX_GetHashCode( FX_LPCSTR pStr);
-FX_DWORD FX_IOSGetMatchFamilyNameHashcode(FX_LPCSTR pFontName);
-FX_UINT32 FX_IOSGetFamilyNamesCount();
-FX_LPCSTR FX_IOSGetFamilyName( FX_UINT32 uIndex);
-#endif
-#endif
+// 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 _APPLE_INT_H_
+#define _APPLE_INT_H_
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+#if _FX_OS_ == _FX_MACOSX_
+#include <Carbon/Carbon.h>
+#endif
+typedef enum eFXIOSFONTCHARSET {
+ eFXFontCharsetDEFAULT = 0,
+ eFXFontCharsetANSI = 1,
+ eFXFontCharsetSYMBOL = 1 << 1,
+ eFXFontCharsetSHIFTJIS = 1 << 2,
+ eFXFontCharsetHANGEUL = 1 << 3,
+ eFXFontCharsetGB2312 = 1 << 4,
+ eFXFontCharsetCHINESEBIG5 = 1 << 5,
+ eFXFontCharsetTHAI = 1 << 6,
+ eFXFontCharsetEASTEUROPE = 1 << 7,
+ eFXFontCharsetRUSSIAN = 1 << 8,
+ eFXFontCharsetGREEK = 1 << 9,
+ eFXFontCharsetTURKISH = 1 << 10,
+ eFXFontCharsetHEBREW = 1 << 11,
+ eFXFontCharsetARABIC = 1 << 12,
+ eFXFontCharsetBALTIC = 1 << 13,
+} FX_IOSCHARSET;
+FX_IOSCHARSET FX_GetiOSCharset(int charset);
+typedef enum eFXIOSFONTFLAG {
+ eFXFontFlagBold = 1,
+ eFXFontFlagItalic = 1 << 1,
+ eFXFontFlagFixedPitch = 1 << 2,
+ eFXFontFlagSerif = 1 << 3,
+ eFXFontFlagScript = 1 << 4,
+} FX_IOSFONTFLAG;
+typedef struct _IOS_FONTDATA {
+ FX_DWORD nHashCode;
+ const char* psName;
+ FX_DWORD charsets;
+ FX_DWORD styles;
+} IOS_FONTDATA;
+class CQuartz2D
+{
+public:
+ void* createGraphics(CFX_DIBitmap* bitmap);
+ void destroyGraphics(void* graphics);
+
+ void* CreateFont(FX_LPCBYTE pFontData, FX_DWORD dwFontSize);
+ void DestroyFont(void* pFont);
+ void setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix);
+ FX_BOOL drawGraphicsString(void* graphics,
+ void* font,
+ FX_FLOAT fontSize,
+ FX_WORD* glyphIndices,
+ CGPoint* glyphPositions,
+ FX_INT32 chars,
+ FX_ARGB argb,
+ CFX_AffineMatrix* matrix = NULL);
+ void saveGraphicsState(void* graphics);
+ void restoreGraphicsState(void* graphics);
+};
+class CApplePlatform : public CFX_Object
+{
+public:
+ CApplePlatform()
+ {
+ m_pFontMapper = NULL;
+ }
+ ~CApplePlatform()
+ {
+ if (m_pFontMapper) {
+ delete m_pFontMapper;
+ }
+ }
+ CQuartz2D _quartz2d;
+ IFX_FontMapper* m_pFontMapper;
+};
+class CFX_QuartzDeviceDriver : public IFX_RenderDeviceDriver
+{
+public:
+ CFX_QuartzDeviceDriver(CGContextRef context, FX_INT32 deviceClass);
+ virtual ~CFX_QuartzDeviceDriver();
+
+ virtual int GetDeviceCaps(int caps_id);
+ virtual CFX_Matrix GetCTM() const;
+ virtual CFX_DIBitmap* GetBackDrop()
+ {
+ return NULL;
+ }
+ virtual void* GetPlatformSurface()
+ {
+ return NULL;
+ }
+ virtual FX_BOOL IsPSPrintDriver()
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL StartRendering()
+ {
+ return TRUE;
+ }
+ virtual void EndRendering() {}
+ virtual void SaveState();
+ virtual void RestoreState(FX_BOOL bKeepSaved);
+ virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ int fill_mode
+ );
+ virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState
+ );
+ virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag = 0,
+ void* pIccTransform = NULL,
+ int blend_type = FXDIB_BLEND_NORMAL
+ );
+ virtual FX_BOOL SetPixel(int x, int y, FX_DWORD color,
+ int alpha_flag = 0, void* pIccTransform = NULL)
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL FillRect(const FX_RECT* pRect, FX_DWORD fill_color,
+ int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
+ virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
+ int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
+ virtual FX_BOOL GetClipBox(FX_RECT* pRect);
+ virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE);
+ virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect,
+ int dest_left, int dest_top, int blend_type,
+ int alpha_flag = 0, void* pIccTransform = NULL);
+ virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
+ virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD flags, FX_LPVOID& handle,
+ int alpha_flag = 0, void* pIccTransform = NULL,
+ int blend_type = FXDIB_BLEND_NORMAL)
+ {
+ return FALSE;
+ }
+ virtual FX_BOOL ContinueDIBits(FX_LPVOID handle, IFX_Pause* pPause)
+ {
+ return FALSE;
+ }
+ virtual void CancelDIBits(FX_LPVOID handle) {}
+ virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
+ CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
+ int alpha_flag = 0, void* pIccTransform = NULL);
+ virtual void ClearDriver();
+protected:
+ void setStrokeInfo(const CFX_GraphStateData * graphState, FX_ARGB argb, FX_FLOAT lineWidth);
+ void setFillInfo(FX_ARGB argb);
+ void setPathToContext(const CFX_PathData * pathData);
+ FX_FLOAT getLineWidth(const CFX_GraphStateData * graphState, CGAffineTransform ctm);
+ FX_BOOL CG_DrawGlypRun(int nChars,
+ const FXTEXT_CHARPOS* pCharPos,
+ CFX_Font* pFont,
+ CFX_FontCache* pCache,
+ const CFX_AffineMatrix* pGlyphMatrix,
+ const CFX_AffineMatrix* pObject2Device,
+ FX_FLOAT font_size,
+ FX_DWORD argb,
+ int alpha_flag,
+ void* pIccTransform);
+ void CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height, CGRect* rect = NULL);
+protected:
+ CGContextRef _context;
+ CGAffineTransform _foxitDevice2User;
+ CGAffineTransform _user2FoxitDevice;
+ FX_INT32 m_saveCount;
+
+ FX_INT32 _width;
+ FX_INT32 _height;
+ FX_INT32 _bitsPerPixel;
+ FX_INT32 _deviceClass;
+ FX_INT32 _renderCaps;
+ FX_INT32 _horzSize;
+ FX_INT32 _vertSize;
+};
+class CFX_FontProvider : public IFX_FileRead
+{
+public:
+ virtual void Release()
+ {
+ delete this;
+ }
+ virtual FX_FILESIZE GetSize()
+ {
+ return (FX_FILESIZE)_totalSize;
+ }
+ virtual FX_BOOL ReadBlock(void* buffer, FX_FILESIZE offset, size_t size);
+
+ virtual FX_BOOL IsEOF()
+ {
+ return _offSet == _totalSize;
+ }
+ virtual FX_FILESIZE GetPosition()
+ {
+ return (FX_FILESIZE)_offSet;
+ }
+ virtual size_t ReadBlock(void* buffer, size_t size);
+public:
+ CFX_FontProvider(CGFontRef cgFont);
+ ~CFX_FontProvider();
+ void InitTableOffset();
+ unsigned long Read(unsigned long offset, unsigned char *buffer, unsigned long count);
+protected:
+ uint32_t CalcTableCheckSum(const uint32_t *table, uint32_t numberOfBytesInTable);
+ uint32_t CalcTableDataRefCheckSum(CFDataRef dataRef);
+private:
+ CGFontRef m_cgFont;
+ UInt32 m_iTableSize;
+ size_t _offSet;
+ typedef struct FontHeader {
+ int32_t fVersion;
+ uint16_t fNumTables;
+ uint16_t fSearchRange;
+ uint16_t fEntrySelector;
+ uint16_t fRangeShift;
+ } FontHeader;
+ typedef struct TableEntry {
+ uint32_t fTag;
+ uint32_t fCheckSum;
+ uint32_t fOffset;
+ uint32_t fLength;
+ } TableEntry;
+ FontHeader _fontHeader;
+ unsigned char * _tableEntries;
+ size_t * _tableOffsets;
+ int _tableCount;
+ int _totalSize;
+};
+FX_UINT32 FX_GetHashCode( FX_LPCSTR pStr);
+FX_DWORD FX_IOSGetMatchFamilyNameHashcode(FX_LPCSTR pFontName);
+FX_UINT32 FX_IOSGetFamilyNamesCount();
+FX_LPCSTR FX_IOSGetFamilyName( FX_UINT32 uIndex);
+#endif
+#endif
diff --git a/core/src/fxge/apple/fx_apple_platform.cpp b/core/src/fxge/apple/fx_apple_platform.cpp
index 229d1785da..7bc1232900 100644
--- a/core/src/fxge/apple/fx_apple_platform.cpp
+++ b/core/src/fxge/apple/fx_apple_platform.cpp
@@ -1,173 +1,173 @@
-// 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 "../../../include/fxcrt/fx_ext.h"
-#include "../../../include/fxge/fx_ge.h"
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-#include "apple_int.h"
-#include "../../../include/fxge/fx_ge_apple.h"
-#include "../agg/include/fxfx_agg_clip_liang_barsky.h"
-#include "../ge/text_int.h"
-#include "../dib/dib_int.h"
-#include "../agg/include/fx_agg_driver.h"
-#include "../../../include/fxge/fx_freetype.h"
-#if (_FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && (!defined(_FPDFAPI_MINI_)))
-void CFX_AggDeviceDriver::InitPlatform()
-{
- CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
- m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap);
-}
-void CFX_AggDeviceDriver::DestroyPlatform()
-{
- CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
- if (m_pPlatformGraphics) {
- quartz2d.destroyGraphics(m_pPlatformGraphics);
- m_pPlatformGraphics = NULL;
- }
-}
-void CFX_FaceCache::InitPlatform() {}
-void CFX_FaceCache::DestroyPlatform() {}
-CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font * pFont,
- FX_DWORD glyph_index,
- const CFX_AffineMatrix * pMatrix,
- int dest_width,
- int anti_alias)
-{
- return NULL;
-}
-static FX_BOOL _CGDrawGlyphRun(CGContextRef pContext,
- int nChars,
- const FXTEXT_CHARPOS* pCharPos,
- CFX_Font* pFont,
- CFX_FontCache* pCache,
- const CFX_AffineMatrix* pObject2Device,
- FX_FLOAT font_size,
- FX_DWORD argb,
- int alpha_flag,
- void* pIccTransform)
-{
- if (nChars == 0) {
- return TRUE;
- }
- CFX_AffineMatrix new_matrix;
- FX_BOOL bNegSize = font_size < 0;
- if (bNegSize) {
- font_size = -font_size;
- }
- FX_FLOAT ori_x = pCharPos[0].m_OriginX, ori_y = pCharPos[0].m_OriginY;
- new_matrix.Transform(ori_x, ori_y);
- if (pObject2Device) {
- new_matrix.Concat(*pObject2Device);
- }
- CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
- if (!pFont->m_pPlatformFont) {
- if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
- return FALSE;
- }
- pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize);
- if (NULL == pFont->m_pPlatformFont) {
- return FALSE;
- }
- }
- CFX_FixedBufGrow<FX_WORD, 32> glyph_indices(nChars);
- CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars);
- for (int i = 0; i < nChars; i++ ) {
- glyph_indices[i] = pCharPos[i].m_ExtGID;
- if (bNegSize) {
- glyph_positions[i].x = -pCharPos[i].m_OriginX;
- } else {
- glyph_positions[i].x = pCharPos[i].m_OriginX;
- }
- glyph_positions[i].y = pCharPos[i].m_OriginY;
- }
- if (bNegSize) {
- new_matrix.a = -new_matrix.a;
- } else {
- new_matrix.b = -new_matrix.b;
- new_matrix.d = -new_matrix.d;
- }
- quartz2d.setGraphicsTextMatrix(pContext, &new_matrix);
- return quartz2d.drawGraphicsString(pContext,
- pFont->m_pPlatformFont,
- font_size,
- glyph_indices,
- glyph_positions,
- nChars,
- argb,
- NULL);
-}
-static void _DoNothing(void *info, const void *data, size_t size) {}
-FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars,
- const FXTEXT_CHARPOS * pCharPos,
- CFX_Font * pFont,
- CFX_FontCache * pCache,
- const CFX_AffineMatrix * pObject2Device,
- FX_FLOAT font_size,
- FX_DWORD argb,
- int alpha_flag, void* pIccTransform)
-{
- if (!pFont) {
- return FALSE;
- }
- FX_BOOL bBold = pFont->IsBold();
- if (!bBold && pFont->GetSubstFont() &&
- pFont->GetSubstFont()->m_Weight >= 500 &&
- pFont->GetSubstFont()->m_Weight <= 600) {
- return FALSE;
- }
- for (int i = 0; i < nChars; i ++) {
- if (pCharPos[i].m_bGlyphAdjust) {
- return FALSE;
- }
- }
- CGContextRef ctx = CGContextRef(m_pPlatformGraphics);
- if (NULL == ctx) {
- return FALSE;
- }
- CGContextSaveGState(ctx);
- CGContextSetTextDrawingMode(ctx, kCGTextFillClip);
- CGRect rect_cg;
- CGImageRef pImageCG = NULL;
- if (m_pClipRgn) {
- rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height());
- const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask();
- if (pClipMask) {
- CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL,
- pClipMask->GetBuffer(),
- pClipMask->GetPitch() * pClipMask->GetHeight(),
- _DoNothing);
- CGFloat decode_f[2] = {255.f, 0.f};
- pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(),
- 8, 8, pClipMask->GetPitch(), pClipMaskDataProvider,
- decode_f, FALSE);
- CGDataProviderRelease(pClipMaskDataProvider);
- }
- } else {
- rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight());
- }
- rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg);
- if (pImageCG) {
- CGContextClipToMask(ctx, rect_cg, pImageCG);
- } else {
- CGContextClipToRect(ctx, rect_cg);
- }
- FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform);
- if (pImageCG) {
- CGImageRelease(pImageCG);
- }
- CGContextRestoreGState(ctx);
- return ret;
-}
-void CFX_Font::ReleasePlatformResource()
-{
- if (m_pPlatformFont) {
- CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
- quartz2d.DestroyFont(m_pPlatformFont);
- m_pPlatformFont = NULL;
- }
-}
-#endif
-#endif
+// 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 "../../../include/fxcrt/fx_ext.h"
+#include "../../../include/fxge/fx_ge.h"
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+#include "apple_int.h"
+#include "../../../include/fxge/fx_ge_apple.h"
+#include "../agg/include/fxfx_agg_clip_liang_barsky.h"
+#include "../ge/text_int.h"
+#include "../dib/dib_int.h"
+#include "../agg/include/fx_agg_driver.h"
+#include "../../../include/fxge/fx_freetype.h"
+#if (_FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && (!defined(_FPDFAPI_MINI_)))
+void CFX_AggDeviceDriver::InitPlatform()
+{
+ CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
+ m_pPlatformGraphics = quartz2d.createGraphics(m_pBitmap);
+}
+void CFX_AggDeviceDriver::DestroyPlatform()
+{
+ CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
+ if (m_pPlatformGraphics) {
+ quartz2d.destroyGraphics(m_pPlatformGraphics);
+ m_pPlatformGraphics = NULL;
+ }
+}
+void CFX_FaceCache::InitPlatform() {}
+void CFX_FaceCache::DestroyPlatform() {}
+CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font * pFont,
+ FX_DWORD glyph_index,
+ const CFX_AffineMatrix * pMatrix,
+ int dest_width,
+ int anti_alias)
+{
+ return NULL;
+}
+static FX_BOOL _CGDrawGlyphRun(CGContextRef pContext,
+ int nChars,
+ const FXTEXT_CHARPOS* pCharPos,
+ CFX_Font* pFont,
+ CFX_FontCache* pCache,
+ const CFX_AffineMatrix* pObject2Device,
+ FX_FLOAT font_size,
+ FX_DWORD argb,
+ int alpha_flag,
+ void* pIccTransform)
+{
+ if (nChars == 0) {
+ return TRUE;
+ }
+ CFX_AffineMatrix new_matrix;
+ FX_BOOL bNegSize = font_size < 0;
+ if (bNegSize) {
+ font_size = -font_size;
+ }
+ FX_FLOAT ori_x = pCharPos[0].m_OriginX, ori_y = pCharPos[0].m_OriginY;
+ new_matrix.Transform(ori_x, ori_y);
+ if (pObject2Device) {
+ new_matrix.Concat(*pObject2Device);
+ }
+ CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
+ if (!pFont->m_pPlatformFont) {
+ if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
+ return FALSE;
+ }
+ pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize);
+ if (NULL == pFont->m_pPlatformFont) {
+ return FALSE;
+ }
+ }
+ CFX_FixedBufGrow<FX_WORD, 32> glyph_indices(nChars);
+ CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars);
+ for (int i = 0; i < nChars; i++ ) {
+ glyph_indices[i] = pCharPos[i].m_ExtGID;
+ if (bNegSize) {
+ glyph_positions[i].x = -pCharPos[i].m_OriginX;
+ } else {
+ glyph_positions[i].x = pCharPos[i].m_OriginX;
+ }
+ glyph_positions[i].y = pCharPos[i].m_OriginY;
+ }
+ if (bNegSize) {
+ new_matrix.a = -new_matrix.a;
+ } else {
+ new_matrix.b = -new_matrix.b;
+ new_matrix.d = -new_matrix.d;
+ }
+ quartz2d.setGraphicsTextMatrix(pContext, &new_matrix);
+ return quartz2d.drawGraphicsString(pContext,
+ pFont->m_pPlatformFont,
+ font_size,
+ glyph_indices,
+ glyph_positions,
+ nChars,
+ argb,
+ NULL);
+}
+static void _DoNothing(void *info, const void *data, size_t size) {}
+FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars,
+ const FXTEXT_CHARPOS * pCharPos,
+ CFX_Font * pFont,
+ CFX_FontCache * pCache,
+ const CFX_AffineMatrix * pObject2Device,
+ FX_FLOAT font_size,
+ FX_DWORD argb,
+ int alpha_flag, void* pIccTransform)
+{
+ if (!pFont) {
+ return FALSE;
+ }
+ FX_BOOL bBold = pFont->IsBold();
+ if (!bBold && pFont->GetSubstFont() &&
+ pFont->GetSubstFont()->m_Weight >= 500 &&
+ pFont->GetSubstFont()->m_Weight <= 600) {
+ return FALSE;
+ }
+ for (int i = 0; i < nChars; i ++) {
+ if (pCharPos[i].m_bGlyphAdjust) {
+ return FALSE;
+ }
+ }
+ CGContextRef ctx = CGContextRef(m_pPlatformGraphics);
+ if (NULL == ctx) {
+ return FALSE;
+ }
+ CGContextSaveGState(ctx);
+ CGContextSetTextDrawingMode(ctx, kCGTextFillClip);
+ CGRect rect_cg;
+ CGImageRef pImageCG = NULL;
+ if (m_pClipRgn) {
+ rect_cg = CGRectMake(m_pClipRgn->GetBox().left, m_pClipRgn->GetBox().top, m_pClipRgn->GetBox().Width(), m_pClipRgn->GetBox().Height());
+ const CFX_DIBitmap* pClipMask = m_pClipRgn->GetMask();
+ if (pClipMask) {
+ CGDataProviderRef pClipMaskDataProvider = CGDataProviderCreateWithData(NULL,
+ pClipMask->GetBuffer(),
+ pClipMask->GetPitch() * pClipMask->GetHeight(),
+ _DoNothing);
+ CGFloat decode_f[2] = {255.f, 0.f};
+ pImageCG = CGImageMaskCreate(pClipMask->GetWidth(), pClipMask->GetHeight(),
+ 8, 8, pClipMask->GetPitch(), pClipMaskDataProvider,
+ decode_f, FALSE);
+ CGDataProviderRelease(pClipMaskDataProvider);
+ }
+ } else {
+ rect_cg = CGRectMake(0, 0, m_pBitmap->GetWidth(), m_pBitmap->GetHeight());
+ }
+ rect_cg = CGContextConvertRectToDeviceSpace(ctx, rect_cg);
+ if (pImageCG) {
+ CGContextClipToMask(ctx, rect_cg, pImageCG);
+ } else {
+ CGContextClipToRect(ctx, rect_cg);
+ }
+ FX_BOOL ret = _CGDrawGlyphRun(ctx, nChars, pCharPos, pFont, pCache, pObject2Device, font_size, argb, alpha_flag, pIccTransform);
+ if (pImageCG) {
+ CGImageRelease(pImageCG);
+ }
+ CGContextRestoreGState(ctx);
+ return ret;
+}
+void CFX_Font::ReleasePlatformResource()
+{
+ if (m_pPlatformFont) {
+ CQuartz2D & quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
+ quartz2d.DestroyFont(m_pPlatformFont);
+ m_pPlatformFont = NULL;
+ }
+}
+#endif
+#endif
diff --git a/core/src/fxge/apple/fx_mac_imp.cpp b/core/src/fxge/apple/fx_mac_imp.cpp
index 9a1218bf0b..a21aa5ded5 100644
--- a/core/src/fxge/apple/fx_mac_imp.cpp
+++ b/core/src/fxge/apple/fx_mac_imp.cpp
@@ -1,117 +1,117 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#include "apple_int.h"
-#if _FX_OS_ == _FX_MACOSX_
-static const struct {
- FX_LPCSTR m_pName;
- FX_LPCSTR m_pSubstName;
-}
-Base14Substs[] = {
- {"Courier", "Courier New"},
- {"Courier-Bold", "Courier New Bold"},
- {"Courier-BoldOblique", "Courier New Bold Italic"},
- {"Courier-Oblique", "Courier New Italic"},
- {"Helvetica", "Arial"},
- {"Helvetica-Bold", "Arial Bold"},
- {"Helvetica-BoldOblique", "Arial Bold Italic"},
- {"Helvetica-Oblique", "Arial Italic"},
- {"Times-Roman", "Times New Roman"},
- {"Times-Bold", "Times New Roman Bold"},
- {"Times-BoldItalic", "Times New Roman Bold Italic"},
- {"Times-Italic", "Times New Roman Italic"},
-};
-#if !defined(_FPDFAPI_MINI_)
-class CFX_MacFontInfo : public CFX_FolderFontInfo
-{
-public:
- virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL& bExact);
-};
-#define JAPAN_GOTHIC "Hiragino Kaku Gothic Pro W6"
-#define JAPAN_MINCHO "Hiragino Mincho Pro W6"
-static void GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family)
-{
- if (face.Find("Gothic") >= 0) {
- face = JAPAN_GOTHIC;
- return;
- }
- if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) {
- face = JAPAN_GOTHIC;
- } else {
- face = JAPAN_MINCHO;
- }
-}
-void* CFX_MacFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact)
-{
- CFX_ByteString face = cstr_face;
- int iBaseFont;
- for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++)
- if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) {
- face = Base14Substs[iBaseFont].m_pSubstName;
- bExact = TRUE;
- break;
- }
- if (iBaseFont < 12) {
- return GetFont(face);
- }
- FX_LPVOID p;
- if (m_FontList.Lookup(face, p)) {
- return p;
- }
- if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) {
- return GetFont("Courier New");
- }
- if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_SYMBOL_CHARSET) {
- return NULL;
- }
- switch (charset) {
- case FXFONT_SHIFTJIS_CHARSET:
- GetJapanesePreference(face, weight, pitch_family);
- break;
- case FXFONT_GB2312_CHARSET:
- face = "STSong";
- break;
- case FXFONT_HANGEUL_CHARSET:
- face = "AppleMyungjo";
- break;
- case FXFONT_CHINESEBIG5_CHARSET:
- face = "LiSong Pro Light";
- }
- if (m_FontList.Lookup(face, p)) {
- return p;
- }
- return NULL;
-}
-#endif
-IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
-{
-#if !defined(_FPDFAPI_MINI_)
- CFX_MacFontInfo* pInfo = FX_NEW CFX_MacFontInfo;
- if (!pInfo) {
- return NULL;
- }
- pInfo->AddPath("~/Library/Fonts");
- pInfo->AddPath("/Library/Fonts");
- pInfo->AddPath("/System/Library/Fonts");
- return pInfo;
-#else
- return NULL;
-#endif
-}
-void CFX_GEModule::InitPlatform()
-{
- m_pPlatformData = FX_NEW CApplePlatform;
- m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
-}
-void CFX_GEModule::DestroyPlatform()
-{
- if (m_pPlatformData) {
- delete (CApplePlatform *) m_pPlatformData;
- }
- m_pPlatformData = NULL;
-}
-#endif
+// 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 "../../../include/fxge/fx_ge.h"
+#include "apple_int.h"
+#if _FX_OS_ == _FX_MACOSX_
+static const struct {
+ FX_LPCSTR m_pName;
+ FX_LPCSTR m_pSubstName;
+}
+Base14Substs[] = {
+ {"Courier", "Courier New"},
+ {"Courier-Bold", "Courier New Bold"},
+ {"Courier-BoldOblique", "Courier New Bold Italic"},
+ {"Courier-Oblique", "Courier New Italic"},
+ {"Helvetica", "Arial"},
+ {"Helvetica-Bold", "Arial Bold"},
+ {"Helvetica-BoldOblique", "Arial Bold Italic"},
+ {"Helvetica-Oblique", "Arial Italic"},
+ {"Times-Roman", "Times New Roman"},
+ {"Times-Bold", "Times New Roman Bold"},
+ {"Times-BoldItalic", "Times New Roman Bold Italic"},
+ {"Times-Italic", "Times New Roman Italic"},
+};
+#if !defined(_FPDFAPI_MINI_)
+class CFX_MacFontInfo : public CFX_FolderFontInfo
+{
+public:
+ virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL& bExact);
+};
+#define JAPAN_GOTHIC "Hiragino Kaku Gothic Pro W6"
+#define JAPAN_MINCHO "Hiragino Mincho Pro W6"
+static void GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family)
+{
+ if (face.Find("Gothic") >= 0) {
+ face = JAPAN_GOTHIC;
+ return;
+ }
+ if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) {
+ face = JAPAN_GOTHIC;
+ } else {
+ face = JAPAN_MINCHO;
+ }
+}
+void* CFX_MacFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact)
+{
+ CFX_ByteString face = cstr_face;
+ int iBaseFont;
+ for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++)
+ if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) {
+ face = Base14Substs[iBaseFont].m_pSubstName;
+ bExact = TRUE;
+ break;
+ }
+ if (iBaseFont < 12) {
+ return GetFont(face);
+ }
+ FX_LPVOID p;
+ if (m_FontList.Lookup(face, p)) {
+ return p;
+ }
+ if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) {
+ return GetFont("Courier New");
+ }
+ if (charset == FXFONT_ANSI_CHARSET || charset == FXFONT_SYMBOL_CHARSET) {
+ return NULL;
+ }
+ switch (charset) {
+ case FXFONT_SHIFTJIS_CHARSET:
+ GetJapanesePreference(face, weight, pitch_family);
+ break;
+ case FXFONT_GB2312_CHARSET:
+ face = "STSong";
+ break;
+ case FXFONT_HANGEUL_CHARSET:
+ face = "AppleMyungjo";
+ break;
+ case FXFONT_CHINESEBIG5_CHARSET:
+ face = "LiSong Pro Light";
+ }
+ if (m_FontList.Lookup(face, p)) {
+ return p;
+ }
+ return NULL;
+}
+#endif
+IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
+{
+#if !defined(_FPDFAPI_MINI_)
+ CFX_MacFontInfo* pInfo = FX_NEW CFX_MacFontInfo;
+ if (!pInfo) {
+ return NULL;
+ }
+ pInfo->AddPath("~/Library/Fonts");
+ pInfo->AddPath("/Library/Fonts");
+ pInfo->AddPath("/System/Library/Fonts");
+ return pInfo;
+#else
+ return NULL;
+#endif
+}
+void CFX_GEModule::InitPlatform()
+{
+ m_pPlatformData = FX_NEW CApplePlatform;
+ m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
+}
+void CFX_GEModule::DestroyPlatform()
+{
+ if (m_pPlatformData) {
+ delete (CApplePlatform *) m_pPlatformData;
+ }
+ m_pPlatformData = NULL;
+}
+#endif
diff --git a/core/src/fxge/apple/fx_quartz_device.cpp b/core/src/fxge/apple/fx_quartz_device.cpp
index bef45163f7..7cb94f1093 100644
--- a/core/src/fxge/apple/fx_quartz_device.cpp
+++ b/core/src/fxge/apple/fx_quartz_device.cpp
@@ -1,1138 +1,1138 @@
-// 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 "../../../include/fxcrt/fx_ext.h"
-#include "../../../include/fxge/fx_ge.h"
-#include "../agg/include/fxfx_agg_clip_liang_barsky.h"
-#include "../ge/text_int.h"
-#include "../dib/dib_int.h"
-#include "../agg/include/fx_agg_driver.h"
-#include "../../../include/fxge/fx_freetype.h"
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
-#include "apple_int.h"
-#include "../../../include/fxge/fx_ge_apple.h"
-#ifndef CGFLOAT_IS_DOUBLE
-#error Expected CGFLOAT_IS_DOUBLE to be defined by CoreGraphics headers
-#endif
-void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap)
-{
- if (!pBitmap) {
- return NULL;
- }
- CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little;
- switch (pBitmap->GetFormat()) {
- case FXDIB_Rgb32:
- bmpInfo |= kCGImageAlphaNoneSkipFirst;
- break;
- case FXDIB_Argb:
- default:
- return NULL;
- }
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(),
- pBitmap->GetWidth(),
- pBitmap->GetHeight(),
- 8,
- pBitmap->GetPitch(),
- colorSpace,
- bmpInfo);
- CGColorSpaceRelease(colorSpace);
- return context;
-}
-void CQuartz2D::destroyGraphics(void* graphics)
-{
- if (graphics) {
- CGContextRelease((CGContextRef) graphics);
- }
-}
-void* CQuartz2D::CreateFont(FX_LPCBYTE pFontData, FX_DWORD dwFontSize)
-{
- CGDataProviderRef pDataProvider = CGDataProviderCreateWithData(NULL, pFontData, (size_t)dwFontSize, NULL);
- if (NULL == pDataProvider) {
- return NULL;
- }
- CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider);
- CGDataProviderRelease(pDataProvider);
- return pCGFont;
-}
-void CQuartz2D::DestroyFont(void* pFont)
-{
- CGFontRelease((CGFontRef)pFont);
-}
-void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix)
-{
- if (!graphics || !matrix) {
- return;
- }
- CGContextRef context = (CGContextRef) graphics;
- CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f;
- CGContextSetTextMatrix(context, CGAffineTransformMake(matrix->a,
- matrix->b,
- matrix->c,
- matrix->d,
- matrix->e,
- ty));
-}
-FX_BOOL CQuartz2D::drawGraphicsString(void* graphics,
- void* font,
- FX_FLOAT fontSize,
- FX_WORD* glyphIndices,
- CGPoint* glyphPositions,
- FX_INT32 charsCount,
- FX_ARGB argb,
- CFX_AffineMatrix* matrix )
-{
- if (!graphics) {
- return FALSE;
- }
- CGContextRef context = (CGContextRef) graphics;
- CGContextSetFont(context, (CGFontRef)font);
- CGContextSetFontSize(context, fontSize);
- if (matrix) {
- CGAffineTransform m = CGContextGetTextMatrix(context);
- m = CGAffineTransformConcat(m,
- CGAffineTransformMake(matrix->a,
- matrix->b,
- matrix->c,
- matrix->d,
- matrix->e,
- matrix->f));
- CGContextSetTextMatrix(context, m);
- }
- FX_INT32 a, r, g, b;
- ArgbDecode(argb, a, r, g, b);
- CGContextSetRGBFillColor(context,
- r / 255.f,
- g / 255.f,
- b / 255.f,
- a / 255.f);
- CGContextSaveGState(context);
-#if CGFLOAT_IS_DOUBLE
- CGPoint* glyphPositionsCG = new CGPoint[charsCount];
- if (!glyphPositionsCG) {
- return FALSE;
- }
- for (int index = 0; index < charsCount; ++index) {
- glyphPositionsCG[index].x = glyphPositions[index].x;
- glyphPositionsCG[index].y = glyphPositions[index].y;
- }
-#else
- CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions;
-#endif
- CGContextShowGlyphsAtPositions(context,
- (CGGlyph *) glyphIndices,
- glyphPositionsCG,
- charsCount);
-#if CGFLOAT_IS_DOUBLE
- delete[] glyphPositionsCG;
-#endif
- CGContextRestoreGState(context);
- return TRUE;
-}
-void CQuartz2D::saveGraphicsState(void * graphics)
-{
- if (graphics) {
- CGContextSaveGState((CGContextRef) graphics);
- }
-}
-void CQuartz2D::restoreGraphicsState(void * graphics)
-{
- if (graphics) {
- CGContextRestoreGState((CGContextRef) graphics);
- }
-}
-static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap)
-{
- if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) {
- return NULL;
- }
- CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little;
- if (pBitmap->HasAlpha()) {
- bitmapInfo |= kCGImageAlphaPremultipliedFirst;
- } else {
- bitmapInfo |= kCGImageAlphaNoneSkipFirst;
- }
- CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
- CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(),
- pBitmap->GetWidth(),
- pBitmap->GetHeight(),
- 8,
- pBitmap->GetPitch(),
- colorSpace,
- bitmapInfo);
- CGColorSpaceRelease(colorSpace);
- return context;
-}
-CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context, FX_INT32 deviceClass)
-{
- m_saveCount = 0;
- _context = context;
- _deviceClass = deviceClass;
- CGContextRetain(_context);
- CGRect r = CGContextGetClipBoundingBox(context);
- _width = FXSYS_round(r.size.width);
- _height = FXSYS_round(r.size.height);
- _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE |
- FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE |
- FXRC_BIT_MASK | FXRC_ALPHA_MASK;
- if (_deviceClass != FXDC_DISPLAY) {
- } else {
- CGImageRef image = CGBitmapContextCreateImage(_context);
- if (image) {
- _renderCaps |= FXRC_GET_BITS;
- _width = CGImageGetWidth(image);
- _height = CGImageGetHeight(image);
- CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image);
- if (kCGImageAlphaPremultipliedFirst == alphaInfo ||
- kCGImageAlphaPremultipliedLast == alphaInfo ||
- kCGImageAlphaOnly == alphaInfo) {
- _renderCaps |= FXRC_ALPHA_OUTPUT;
- }
- }
- CGImageRelease(image);
- }
- CGAffineTransform ctm = CGContextGetCTM(_context);
- CGContextSaveGState(_context);
- m_saveCount++;
- if (ctm.d >= 0) {
- CGFloat offset_x, offset_y;
- offset_x = ctm.tx;
- offset_y = ctm.ty;
- CGContextTranslateCTM(_context, -offset_x, -offset_y);
- CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, _height + offset_y));
- }
- _foxitDevice2User = CGAffineTransformIdentity;
- _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User);
-}
-CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver()
-{
- CGContextRestoreGState(_context);
- m_saveCount--;
- for (int i = 0; i < m_saveCount; ++i) {
- CGContextRestoreGState(_context);
- }
- if (_context) {
- CGContextRelease(_context);
- }
-}
-int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID)
-{
- switch (capsID) {
- case FXDC_DEVICE_CLASS: {
- return _deviceClass;
- }
- case FXDC_PIXEL_WIDTH: {
- return _width;
- }
- case FXDC_PIXEL_HEIGHT: {
- return _height;
- }
- case FXDC_BITS_PIXEL: {
- return 32;
- }
- case FXDC_RENDER_CAPS: {
- return _renderCaps;
- }
- default: {
- return 0;
- }
- }
-}
-CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const
-{
- CGAffineTransform ctm = CGContextGetCTM(_context);
- return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty);
-}
-void CFX_QuartzDeviceDriver::SaveState()
-{
- CGContextSaveGState(_context);
- m_saveCount++;
-}
-void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved )
-{
- CGContextRestoreGState(_context);
- if (isKeepSaved) {
- CGContextSaveGState(_context);
- } else {
- m_saveCount--;
- }
-}
-FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData,
- const CFX_AffineMatrix* matrix,
- int fillMode )
-{
- SaveState();
- CGAffineTransform m = CGAffineTransformIdentity;
- if (matrix) {
- m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF());
- }
- m = CGAffineTransformConcat(m, _foxitDevice2User);
- CGContextConcatCTM(_context, m);
- setPathToContext(pathData);
- RestoreState(FALSE);
- if ((fillMode & 3) == FXFILL_WINDING) {
- CGContextClip(_context);
- } else {
- CGContextEOClip(_context);
- }
- return TRUE;
-}
-FX_FLOAT CFX_QuartzDeviceDriver::getLineWidth(const CFX_GraphStateData * graphState, CGAffineTransform ctm)
-{
- FX_FLOAT lineWidth = graphState->m_LineWidth;
- if (graphState->m_LineWidth <= 0.f) {
- CGSize size;
- size.width = 1;
- size.height = 1;
- CGSize temp = CGSizeApplyAffineTransform(size, ctm);
- CGFloat x = 1 / temp.width;
- CGFloat y = 1 / temp.height;
- lineWidth = x > y ? x : y;
- }
- return lineWidth;
-}
-FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke(const CFX_PathData* pathData,
- const CFX_AffineMatrix* matrix,
- const CFX_GraphStateData* graphState )
-{
- SaveState();
- CGAffineTransform m = CGAffineTransformIdentity;
- if (matrix) {
- m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF());
- }
- m = CGAffineTransformConcat(m, _foxitDevice2User);
- CGContextConcatCTM(_context, m);
- FX_FLOAT lineWidth = getLineWidth(graphState, m);
- setStrokeInfo(graphState, 0xFF000000, lineWidth);
- setPathToContext(pathData);
- CGContextReplacePathWithStrokedPath(_context);
- RestoreState(FALSE);
- CGContextClip(_context);
- return TRUE;
-}
-static CGBlendMode GetCGBlendMode(int blend_type)
-{
- CGBlendMode mode = kCGBlendModeNormal;
- switch (blend_type) {
- case FXDIB_BLEND_NORMAL:
- mode = kCGBlendModeNormal;
- break;
- case FXDIB_BLEND_MULTIPLY:
- mode = kCGBlendModeMultiply;
- break;
- case FXDIB_BLEND_SCREEN:
- mode = kCGBlendModeScreen;
- break;
- case FXDIB_BLEND_OVERLAY:
- mode = kCGBlendModeOverlay;
- break;
- case FXDIB_BLEND_DARKEN:
- mode = kCGBlendModeDarken;
- break;
- case FXDIB_BLEND_LIGHTEN:
- mode = kCGBlendModeLighten;
- break;
- case FXDIB_BLEND_COLORDODGE:
- mode = kCGBlendModeColorDodge;
- break;
- case FXDIB_BLEND_COLORBURN:
- mode = kCGBlendModeColorBurn;
- break;
- case FXDIB_BLEND_HARDLIGHT:
- mode = kCGBlendModeHardLight;
- break;
- case FXDIB_BLEND_SOFTLIGHT:
- mode = kCGBlendModeSoftLight;
- break;
- case FXDIB_BLEND_DIFFERENCE:
- mode = kCGBlendModeDifference;
- break;
- case FXDIB_BLEND_EXCLUSION:
- mode = kCGBlendModeExclusion;
- break;
- case FXDIB_BLEND_HUE:
- mode = kCGBlendModeHue;
- break;
- case FXDIB_BLEND_SATURATION:
- mode = kCGBlendModeSaturation;
- break;
- case FXDIB_BLEND_COLOR:
- mode = kCGBlendModeColor;
- break;
- case FXDIB_BLEND_LUMINOSITY:
- mode = kCGBlendModeLuminosity;
- break;
- default:
- mode = kCGBlendModeNormal;
- break;
- }
- return mode;
-}
-FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData,
- const CFX_AffineMatrix* matrix,
- const CFX_GraphStateData* graphState,
- FX_DWORD fillArgb,
- FX_DWORD strokeArgb,
- int fillMode,
- int alpha_flag,
- void* pIccTransform,
- int blend_type
- )
-{
- SaveState();
- CGBlendMode mode = GetCGBlendMode(blend_type);
- if (mode != kCGBlendModeNormal) {
- CGContextSetBlendMode(_context, mode);
- }
- CGAffineTransform m = CGAffineTransformIdentity;
- if (matrix) {
- m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF());
- }
- m = CGAffineTransformConcat(m, _foxitDevice2User);
- CGContextConcatCTM(_context, m);
- int pathMode = 0;
- if (graphState && strokeArgb) {
- CGContextSetMiterLimit(_context, graphState->m_MiterLimit);
- FX_FLOAT lineWidth = getLineWidth(graphState, m);
- setStrokeInfo(graphState, strokeArgb, lineWidth);
- pathMode |= 4;
- }
- if (fillMode && fillArgb) {
- setFillInfo(fillArgb);
- if ((fillMode & 3) == FXFILL_WINDING) {
- pathMode |= 1;
- } else if ((fillMode & 3) == FXFILL_ALTERNATE) {
- pathMode |= 2;
- }
- }
- setPathToContext(pathData);
- if (fillMode & FXFILL_FULLCOVER) {
- CGContextSetShouldAntialias(_context, false);
- }
- if (pathMode == 4) {
- CGContextStrokePath(_context);
- } else if (pathMode == 1) {
- CGContextFillPath(_context);
- } else if (pathMode == 2) {
- CGContextEOFillPath(_context);
- } else if (pathMode == 5) {
- CGContextDrawPath(_context, kCGPathFillStroke);
- } else if (pathMode == 6) {
- CGContextDrawPath(_context, kCGPathEOFillStroke);
- }
- RestoreState(FALSE);
- return TRUE;
-}
-FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect,
- FX_ARGB fillArgb,
- int alphaFlag ,
- void* iccTransform ,
- int blend_type )
-{
- CGBlendMode mode = GetCGBlendMode(blend_type);
- if (mode != kCGBlendModeNormal) {
- CGContextSetBlendMode(_context, mode);
- }
- CGRect rect_fx = CGRectMake(rect->left, rect->top, rect->Width(), rect->Height());
- CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
- FX_INT32 a, r, g, b;
- ArgbDecode(fillArgb, a, r, g, b);
- CGContextSetRGBFillColor(_context,
- r / 255.f,
- g / 255.f,
- b / 255.f,
- a / 255.f);
- CGContextFillRect(_context, rect_usr);
- if (mode != kCGBlendModeNormal) {
- CGContextSetBlendMode(_context, kCGBlendModeNormal);
- }
- return TRUE;
-}
-FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1,
- FX_FLOAT y1,
- FX_FLOAT x2,
- FX_FLOAT y2,
- FX_DWORD argb,
- int alphaFlag ,
- void* iccTransform ,
- int blend_type )
-{
- CGBlendMode mode = GetCGBlendMode(blend_type);
- if (mode != kCGBlendModeNormal) {
- CGContextSetBlendMode(_context, mode);
- }
- CGPoint pt = CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2User);
- x1 = pt.x;
- y1 = pt.y;
- pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User);
- x2 = pt.x;
- y2 = pt.y;
- FX_INT32 a, r, g, b;
- ArgbDecode(argb, a, r, g, b);
- CGContextSetRGBStrokeColor(_context,
- r / 255.f,
- g / 255.f,
- b / 255.f,
- a / 255.f);
- CGContextMoveToPoint(_context, x1, y1);
- CGContextAddLineToPoint(_context, x2, y2);
- CGContextStrokePath(_context);
- if (mode != kCGBlendModeNormal) {
- CGContextSetBlendMode(_context, kCGBlendModeNormal);
- }
- return TRUE;
-}
-FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect)
-{
- CGRect r = CGContextGetClipBoundingBox(_context);
- r = CGRectApplyAffineTransform(r, _user2FoxitDevice);
- rect->left = FXSYS_floor(r.origin.x);
- rect->top = FXSYS_floor(r.origin.y);
- rect->right = FXSYS_ceil(r.origin.x + r.size.width);
- rect->bottom = FXSYS_ceil(r.origin.y + r.size.height);
- return TRUE;
-}
-FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap,
- FX_INT32 left,
- FX_INT32 top,
- void* pIccTransform,
- FX_BOOL bDEdge)
-{
- if (FXDC_PRINTER == _deviceClass) {
- return FALSE;
- }
- if (bitmap->GetBPP() < 32) {
- return FALSE;
- }
- if (!(_renderCaps | FXRC_GET_BITS)) {
- return FALSE;
- }
- CGPoint pt = CGPointMake(left, top);
- pt = CGPointApplyAffineTransform(pt, _foxitDevice2User);
- CGAffineTransform ctm = CGContextGetCTM(_context);
- pt.x *= FXSYS_fabs(ctm.a);
- pt.y *= FXSYS_fabs(ctm.d);
- CGImageRef image = CGBitmapContextCreateImage(_context);
- if (NULL == image) {
- return FALSE;
- }
- CGFloat width = (CGFloat) bitmap->GetWidth();
- CGFloat height = (CGFloat) bitmap->GetHeight();
- if (width + pt.x > _width) {
- width -= (width + pt.x - _width);
- }
- if (height + pt.y > _height) {
- height -= (height + pt.y - _height);
- }
- CGImageRef subImage = CGImageCreateWithImageInRect(image,
- CGRectMake(pt.x,
- pt.y,
- width,
- height));
- CGContextRef context = createContextWithBitmap(bitmap);
- CGRect rect = CGContextGetClipBoundingBox(context);
- CGContextClearRect(context, rect);
- CGContextDrawImage(context, rect, subImage);
- CGContextRelease(context);
- CGImageRelease(subImage);
- CGImageRelease(image);
- if (bitmap->HasAlpha()) {
- for (int row = 0; row < bitmap->GetHeight(); row ++) {
- FX_LPBYTE pScanline = (FX_LPBYTE)bitmap->GetScanline(row);
- for (int col = 0; col < bitmap->GetWidth(); col ++) {
- if (pScanline[3] > 0) {
- pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f);
- pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f);
- pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f);
- }
- pScanline += 4;
- }
- }
- }
- return TRUE;
-}
-FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap,
- FX_ARGB argb,
- const FX_RECT* srcRect,
- int dest_left,
- int dest_top,
- int blendType,
- int alphaFlag ,
- void* iccTransform )
-{
- SaveState();
- CGFloat src_left, src_top, src_width, src_height;
- if (srcRect) {
- src_left = srcRect->left;
- src_top = srcRect->top;
- src_width = srcRect->Width();
- src_height = srcRect->Height();
- } else {
- src_left = src_top = 0;
- src_width = pBitmap->GetWidth();
- src_height = pBitmap->GetHeight();
- }
- CGAffineTransform ctm = CGContextGetCTM(_context);
- CGFloat scale_x = FXSYS_fabs(ctm.a);
- CGFloat scale_y = FXSYS_fabs(ctm.d);
- src_left /= scale_x;
- src_top /= scale_y;
- src_width /= scale_x;
- src_height /= scale_y;
- CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height);
- CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
- CGContextBeginPath(_context);
- CGContextAddRect(_context, rect_usr);
- CGContextClip(_context);
- rect_usr.size = CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y);
- rect_usr = CGRectOffset(rect_usr, -src_left, -src_top);
- CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr);
- CFX_DIBitmap* pBitmap1 = NULL;
- if (pBitmap->IsAlphaMask()) {
- if (pBitmap->GetBuffer()) {
- pBitmap1 = (CFX_DIBitmap*)pBitmap;
- } else {
- pBitmap1 = pBitmap->Clone();
- }
- if (NULL == pBitmap1) {
- RestoreState(FALSE);
- return FALSE;
- }
- CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
- pBitmap1->GetBuffer(),
- pBitmap1->GetPitch() * pBitmap1->GetHeight(),
- NULL);
- CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
- CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
- CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
- pBitmap1->GetHeight(),
- pBitmap1->GetBPP(),
- pBitmap1->GetBPP(),
- pBitmap1->GetPitch(),
- pColorSpace,
- bitmapInfo,
- pBitmapProvider, NULL, true,
- kCGRenderingIntentDefault);
- CGContextClipToMask(_context, rect_usr, pImage);
- CGContextSetRGBFillColor(_context,
- FXARGB_R(argb) / 255.f,
- FXARGB_G(argb) / 255.f,
- FXARGB_B(argb) / 255.f,
- FXARGB_A(argb) / 255.f);
- CGContextFillRect(_context, rect_usr);
- CGImageRelease(pImage);
- CGColorSpaceRelease(pColorSpace);
- CGDataProviderRelease(pBitmapProvider);
- if (pBitmap1 != pBitmap) {
- delete pBitmap1;
- }
- RestoreState(FALSE);
- return TRUE;
- }
- if (pBitmap->GetBPP() < 32) {
- pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
- } else {
- if (pBitmap->GetBuffer()) {
- pBitmap1 = (CFX_DIBitmap*)pBitmap;
- } else {
- pBitmap1 = pBitmap->Clone();
- }
- }
- if (NULL == pBitmap1) {
- RestoreState(FALSE);
- return FALSE;
- }
- if (pBitmap1->HasAlpha()) {
- if (pBitmap1 == pBitmap) {
- pBitmap1 = pBitmap->Clone();
- if (!pBitmap1) {
- RestoreState(FALSE);
- return FALSE;
- }
- }
- for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
- FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
- for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
- pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
- pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
- pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
- pScanline += 4;
- }
- }
- }
- CGContextRef ctx = createContextWithBitmap(pBitmap1);
- CGImageRef image = CGBitmapContextCreateImage(ctx);
- int blend_mode = blendType;
- if (FXDIB_BLEND_HARDLIGHT == blendType) {
- blend_mode = kCGBlendModeSoftLight;
- } else if (FXDIB_BLEND_SOFTLIGHT == blendType) {
- blend_mode = kCGBlendModeHardLight;
- } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && blendType <= FXDIB_BLEND_LUMINOSITY) {
- blend_mode = blendType - 9;
- } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) {
- blend_mode = kCGBlendModeNormal;
- }
- CGContextSetBlendMode(_context, (CGBlendMode)blend_mode);
- CGContextDrawImage(_context, rect_usr, image);
- CGImageRelease(image);
- CGContextRelease(ctx);
- if (pBitmap1 != pBitmap) {
- delete pBitmap1;
- }
- RestoreState(FALSE);
- return TRUE;
-}
-FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap,
- FX_ARGB argb,
- int dest_left,
- int dest_top,
- int dest_width,
- int dest_height,
- const FX_RECT* clipRect,
- FX_DWORD flags,
- int alphaFlag ,
- void* iccTransform ,
- int blend_type)
-{
- SaveState();
- if (clipRect) {
- CGContextBeginPath(_context);
- CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height());
- rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User);
- CGContextAddRect(_context, rect_clip);
- CGContextClip(_context);
- }
- CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height);
- rect = CGRectApplyAffineTransform(rect, _foxitDevice2User);
- if (FXDIB_BICUBIC_INTERPOL == flags) {
- CGContextSetInterpolationQuality(_context, kCGInterpolationHigh);
- } else if (FXDIB_DOWNSAMPLE == flags) {
- CGContextSetInterpolationQuality(_context, kCGInterpolationNone);
- } else {
- CGContextSetInterpolationQuality(_context, kCGInterpolationMedium);
- }
- CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height);
- CFX_DIBitmap* pBitmap1 = NULL;
- if (pBitmap->IsAlphaMask()) {
- if (pBitmap->GetBuffer()) {
- pBitmap1 = (CFX_DIBitmap*)pBitmap;
- } else {
- pBitmap1 = pBitmap->Clone();
- }
- if (NULL == pBitmap1) {
- RestoreState(FALSE);
- return FALSE;
- }
- CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
- pBitmap1->GetBuffer(),
- pBitmap1->GetPitch() * pBitmap1->GetHeight(),
- NULL);
- CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
- CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
- CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
- pBitmap1->GetHeight(),
- pBitmap1->GetBPP(),
- pBitmap1->GetBPP(),
- pBitmap1->GetPitch(),
- pColorSpace,
- bitmapInfo,
- pBitmapProvider, NULL, true,
- kCGRenderingIntentDefault);
- CGContextClipToMask(_context, rect, pImage);
- CGContextSetRGBFillColor(_context,
- FXARGB_R(argb) / 255.f,
- FXARGB_G(argb) / 255.f,
- FXARGB_B(argb) / 255.f,
- FXARGB_A(argb) / 255.f);
- CGContextFillRect(_context, rect);
- CGImageRelease(pImage);
- CGColorSpaceRelease(pColorSpace);
- CGDataProviderRelease(pBitmapProvider);
- if (pBitmap1 != pBitmap) {
- delete pBitmap1;
- }
- RestoreState(FALSE);
- return TRUE;
- }
- if (pBitmap->GetBPP() < 32) {
- pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
- } else {
- if (pBitmap->GetBuffer()) {
- pBitmap1 = (CFX_DIBitmap*)pBitmap;
- } else {
- pBitmap1 = pBitmap->Clone();
- }
- }
- if (NULL == pBitmap1) {
- RestoreState(FALSE);
- return FALSE;
- }
- if (pBitmap1->HasAlpha()) {
- if (pBitmap1 == pBitmap) {
- pBitmap1 = pBitmap->Clone();
- if (!pBitmap1) {
- RestoreState(FALSE);
- return FALSE;
- }
- }
- for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
- FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
- for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
- pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
- pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
- pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
- pScanline += 4;
- }
- }
- }
- CGContextRef ctx = createContextWithBitmap(pBitmap1);
- CGImageRef image = CGBitmapContextCreateImage(ctx);
- CGContextDrawImage(_context, rect, image);
- CGImageRelease(image);
- CGContextRelease(ctx);
- if (pBitmap1 != pBitmap) {
- delete pBitmap1;
- }
- RestoreState(FALSE);
- return TRUE;
-}
-FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun(int nChars,
- const FXTEXT_CHARPOS* pCharPos,
- CFX_Font* pFont,
- CFX_FontCache* pCache,
- const CFX_AffineMatrix* pGlyphMatrix,
- const CFX_AffineMatrix* pObject2Device,
- FX_FLOAT font_size,
- FX_DWORD argb,
- int alpha_flag,
- void* pIccTransform)
-{
- if (nChars == 0) {
- return TRUE;
- }
- CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
- if (!pFont->m_pPlatformFont) {
- if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
- return FALSE;
- }
- pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize);
- if (NULL == pFont->m_pPlatformFont) {
- return FALSE;
- }
- }
- CFX_FixedBufGrow<FX_WORD, 32> glyph_indices(nChars);
- CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars);
- for (int i = 0; i < nChars; i++ ) {
- glyph_indices[i] = pCharPos[i].m_ExtGID;
- glyph_positions[i].x = pCharPos[i].m_OriginX;
- glyph_positions[i].y = pCharPos[i].m_OriginY;
- }
- CFX_AffineMatrix text_matrix;
- if (pObject2Device) {
- text_matrix.Concat(*pObject2Device);
- }
- CGAffineTransform matrix_cg = CGAffineTransformMake(text_matrix.a,
- text_matrix.b,
- text_matrix.c,
- text_matrix.d,
- text_matrix.e,
- text_matrix.f);
- matrix_cg = CGAffineTransformConcat(matrix_cg, _foxitDevice2User);
- CGContextSetTextMatrix(_context, matrix_cg);
- CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont);
- CGContextSetFontSize(_context, FXSYS_fabs(font_size));
- FX_INT32 a, r, g, b;
- ArgbDecode(argb, a, r, g, b);
- CGContextSetRGBFillColor(_context,
- r / 255.f,
- g / 255.f,
- b / 255.f,
- a / 255.f);
- SaveState();
- if (pGlyphMatrix) {
- CGAffineTransform ctm = CGContextGetCTM(_context);
- CGPoint origin = CGPointMake( glyph_positions[0].x, glyph_positions[0].y);
- origin = CGPointApplyAffineTransform(origin, matrix_cg);
- CGContextTranslateCTM(_context, origin.x, origin.y);
- CGAffineTransform glyph_matrix = CGAffineTransformMake(pGlyphMatrix->a,
- pGlyphMatrix->b,
- pGlyphMatrix->c,
- pGlyphMatrix->d,
- pGlyphMatrix->e,
- pGlyphMatrix->f);
- if (_foxitDevice2User.d < 0) {
- glyph_matrix = CGAffineTransformInvert(glyph_matrix);
- }
- CGContextConcatCTM(_context, glyph_matrix);
- CGContextTranslateCTM(_context, -origin.x, -origin.y);
- }
- CGContextShowGlyphsAtPositions(_context,
- (CGGlyph*)glyph_indices,
- glyph_positions,
- nChars);
- RestoreState(FALSE);
- return TRUE;
-}
-FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(int nChars,
- const FXTEXT_CHARPOS* pCharPos,
- CFX_Font* pFont,
- CFX_FontCache* pCache,
- const CFX_AffineMatrix* pObject2Device,
- FX_FLOAT font_size,
- FX_DWORD color,
- int alpha_flag ,
- void* pIccTransform)
-{
- if (NULL == pFont || NULL == _context) {
- return FALSE;
- }
- FX_BOOL bBold = pFont->IsBold();
- if (!bBold && pFont->GetSubstFont() &&
- pFont->GetSubstFont()->m_Weight >= 500 &&
- pFont->GetSubstFont()->m_Weight <= 600) {
- return FALSE;
- }
- SaveState();
- CGContextSetTextDrawingMode(_context, kCGTextFillClip);
- FX_BOOL ret = FALSE;
- FX_INT32 i = 0;
- while (i < nChars) {
- if (pCharPos[i].m_bGlyphAdjust || font_size < 0) {
- if (i > 0) {
- ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform);
- if (!ret) {
- RestoreState(FALSE);
- return ret;
- }
- }
- const FXTEXT_CHARPOS* char_pos = pCharPos + i;
- CFX_AffineMatrix glphy_matrix;
- if (font_size < 0) {
- glphy_matrix.Concat(-1, 0, 0, -1, 0, 0);
- }
- if (char_pos->m_bGlyphAdjust) {
- glphy_matrix.Concat(char_pos->m_AdjustMatrix[0],
- char_pos->m_AdjustMatrix[1],
- char_pos->m_AdjustMatrix[2],
- char_pos->m_AdjustMatrix[3], 0, 0);
- }
- ret = CG_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix, pObject2Device, font_size, color, alpha_flag, pIccTransform);
- if (!ret) {
- RestoreState(FALSE);
- return ret;
- }
- i ++;
- pCharPos += i;
- nChars -= i;
- i = 0;
- } else {
- i ++;
- }
- }
- if (i > 0) {
- ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform);
- }
- RestoreState(FALSE);
- return ret;
-}
-void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, FX_ARGB argb, FX_FLOAT lineWidth)
-{
- if (NULL == graphState) {
- return;
- }
- CGContextSetLineWidth(_context, lineWidth);
- CGLineCap cap;
- switch (graphState->m_LineCap) {
- case CFX_GraphStateData::LineCapRound: {
- cap = kCGLineCapRound;
- break;
- }
- case CFX_GraphStateData::LineCapSquare: {
- cap = kCGLineCapSquare;
- break;
- }
- case CFX_GraphStateData::LineCapButt:
- default: {
- cap = kCGLineCapButt;
- }
- }
- CGContextSetLineCap(_context, cap);
- CGLineJoin join;
- switch (graphState->m_LineJoin) {
- case CFX_GraphStateData::LineJoinRound: {
- join = kCGLineJoinRound;
- break;
- }
- case CFX_GraphStateData::LineJoinBevel: {
- join = kCGLineJoinBevel;
- break;
- }
- case CFX_GraphStateData::LineJoinMiter:
- default: {
- join = kCGLineJoinMiter;
- }
- }
- CGContextSetLineJoin(_context, join);
- if (graphState->m_DashCount) {
-#if CGFLOAT_IS_DOUBLE
- CGFloat* dashArray = new CGFloat[graphState->m_DashCount];
- if (!dashArray) {
- return;
- }
- for (int index = 0; index < graphState->m_DashCount; ++index) {
- dashArray[index] = graphState->m_DashArray[index];
- }
-#else
- CGFloat* dashArray = (CGFloat*)graphState->m_DashArray;
-#endif
- CGContextSetLineDash(_context, graphState->m_DashPhase, dashArray, graphState->m_DashCount);
-#if CGFLOAT_IS_DOUBLE
- delete[] dashArray;
-#endif
- }
- FX_INT32 a, r, g, b;
- ArgbDecode(argb, a, r, g, b);
- CGContextSetRGBStrokeColor(_context,
- r / 255.f,
- g / 255.f,
- b / 255.f,
- a / 255.f);
-}
-void CFX_QuartzDeviceDriver::setFillInfo(FX_ARGB argb)
-{
- FX_INT32 a, r, g, b;
- ArgbDecode(argb, a, r, g, b);
- CGContextSetRGBFillColor(_context,
- r / 255.f,
- g / 255.f,
- b / 255.f,
- a / 255.f);
-}
-void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData)
-{
- FX_INT32 count = pathData->GetPointCount();
- FX_PATHPOINT* points = pathData->GetPoints();
- CGContextBeginPath(_context);
- for (FX_INT32 i = 0; i < count; i ++) {
- switch (points[i].m_Flag & FXPT_TYPE) {
- case FXPT_MOVETO:
- CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_PointY);
- break;
- case FXPT_LINETO:
- CGContextAddLineToPoint(_context, points[i].m_PointX, points[i].m_PointY);
- break;
- case FXPT_BEZIERTO: {
- CGContextAddCurveToPoint(_context,
- points[i].m_PointX, points[i].m_PointY,
- points[i + 1].m_PointX, points[i + 1].m_PointY,
- points[i + 2].m_PointX, points[i + 2].m_PointY);
- i += 2;
- }
- }
- if (points[i].m_Flag & FXPT_CLOSEFIGURE) {
- CGContextClosePath(_context);
- }
- }
-}
-void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height,
- CGRect* rect )
-{
- int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1;
- int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1;
- if (flip_y < 0 || flip_x < 0) {
- if (dest_height < 0) {
- dest_height = -dest_height;
- dest_top -= dest_height;
- }
- CGRect rt = CGRectApplyAffineTransform(CGRectMake(dest_left, dest_top, dest_width, dest_height), _foxitDevice2User);
- CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f,
- offset_y = (rt.origin.y) + rt.size.height / 2.f;
- CGAffineTransform transform = CGAffineTransformIdentity;
- transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y));
- transform = CGAffineTransformConcat(transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0));
- transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y));
- CGContextConcatCTM(_context, transform);
- if (rect) {
- *rect = CGRectApplyAffineTransform(*rect, transform);
- }
- }
-}
-void CFX_QuartzDeviceDriver::ClearDriver()
-{
- if (NULL == _context) {
- return;
- }
- for (int i = 0; i < m_saveCount; ++i) {
- CGContextRestoreGState(_context);
- }
- m_saveCount = 0;
- if (_context) {
- CGContextRelease(_context);
- }
-}
-CFX_QuartzDevice::CFX_QuartzDevice()
-{
- m_bOwnedBitmap = FALSE;
- m_pContext = NULL;
-}
-CFX_QuartzDevice::~CFX_QuartzDevice()
-{
- if (m_pContext) {
- CGContextRelease(m_pContext);
- }
- if (GetBitmap() && m_bOwnedBitmap) {
- delete GetBitmap();
- }
-}
-CGContextRef CFX_QuartzDevice::GetContext()
-{
- return m_pContext;
-}
-FX_BOOL CFX_QuartzDevice::Attach(CGContextRef context, FX_INT32 nDeviceClass)
-{
- if (m_pContext) {
- CGContextRelease(m_pContext);
- }
- m_pContext = context;
- CGContextRetain(m_pContext);
- IFX_RenderDeviceDriver* pDriver = FX_NEW CFX_QuartzDeviceDriver(m_pContext, nDeviceClass);
- if (!pDriver) {
- return FALSE;
- }
- SetDeviceDriver(pDriver);
- return TRUE;
-}
-FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap)
-{
- SetBitmap(pBitmap);
- m_pContext = createContextWithBitmap(pBitmap);
- if (NULL == m_pContext) {
- return FALSE;
- }
- IFX_RenderDeviceDriver* pDriver = FX_NEW CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY);
- if (!pDriver) {
- return FALSE;
- }
- SetDeviceDriver(pDriver);
- return TRUE;
-}
-FX_BOOL CFX_QuartzDevice::Create(FX_INT32 width, FX_INT32 height, FXDIB_Format format)
-{
- if ((FX_BYTE)format < 32) {
- return FALSE;
- }
- CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
- if (!pBitmap) {
- return FALSE;
- }
- if (!pBitmap->Create(width, height, format)) {
- delete pBitmap;
- return FALSE;
- }
- m_bOwnedBitmap = TRUE;
- return Attach(pBitmap);
-}
-#endif
+// 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 "../../../include/fxcrt/fx_ext.h"
+#include "../../../include/fxge/fx_ge.h"
+#include "../agg/include/fxfx_agg_clip_liang_barsky.h"
+#include "../ge/text_int.h"
+#include "../dib/dib_int.h"
+#include "../agg/include/fx_agg_driver.h"
+#include "../../../include/fxge/fx_freetype.h"
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+#include "apple_int.h"
+#include "../../../include/fxge/fx_ge_apple.h"
+#ifndef CGFLOAT_IS_DOUBLE
+#error Expected CGFLOAT_IS_DOUBLE to be defined by CoreGraphics headers
+#endif
+void* CQuartz2D::createGraphics(CFX_DIBitmap* pBitmap)
+{
+ if (!pBitmap) {
+ return NULL;
+ }
+ CGBitmapInfo bmpInfo = kCGBitmapByteOrder32Little;
+ switch (pBitmap->GetFormat()) {
+ case FXDIB_Rgb32:
+ bmpInfo |= kCGImageAlphaNoneSkipFirst;
+ break;
+ case FXDIB_Argb:
+ default:
+ return NULL;
+ }
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(),
+ pBitmap->GetWidth(),
+ pBitmap->GetHeight(),
+ 8,
+ pBitmap->GetPitch(),
+ colorSpace,
+ bmpInfo);
+ CGColorSpaceRelease(colorSpace);
+ return context;
+}
+void CQuartz2D::destroyGraphics(void* graphics)
+{
+ if (graphics) {
+ CGContextRelease((CGContextRef) graphics);
+ }
+}
+void* CQuartz2D::CreateFont(FX_LPCBYTE pFontData, FX_DWORD dwFontSize)
+{
+ CGDataProviderRef pDataProvider = CGDataProviderCreateWithData(NULL, pFontData, (size_t)dwFontSize, NULL);
+ if (NULL == pDataProvider) {
+ return NULL;
+ }
+ CGFontRef pCGFont = CGFontCreateWithDataProvider(pDataProvider);
+ CGDataProviderRelease(pDataProvider);
+ return pCGFont;
+}
+void CQuartz2D::DestroyFont(void* pFont)
+{
+ CGFontRelease((CGFontRef)pFont);
+}
+void CQuartz2D::setGraphicsTextMatrix(void* graphics, CFX_AffineMatrix* matrix)
+{
+ if (!graphics || !matrix) {
+ return;
+ }
+ CGContextRef context = (CGContextRef) graphics;
+ CGFloat ty = CGBitmapContextGetHeight(context) - matrix->f;
+ CGContextSetTextMatrix(context, CGAffineTransformMake(matrix->a,
+ matrix->b,
+ matrix->c,
+ matrix->d,
+ matrix->e,
+ ty));
+}
+FX_BOOL CQuartz2D::drawGraphicsString(void* graphics,
+ void* font,
+ FX_FLOAT fontSize,
+ FX_WORD* glyphIndices,
+ CGPoint* glyphPositions,
+ FX_INT32 charsCount,
+ FX_ARGB argb,
+ CFX_AffineMatrix* matrix )
+{
+ if (!graphics) {
+ return FALSE;
+ }
+ CGContextRef context = (CGContextRef) graphics;
+ CGContextSetFont(context, (CGFontRef)font);
+ CGContextSetFontSize(context, fontSize);
+ if (matrix) {
+ CGAffineTransform m = CGContextGetTextMatrix(context);
+ m = CGAffineTransformConcat(m,
+ CGAffineTransformMake(matrix->a,
+ matrix->b,
+ matrix->c,
+ matrix->d,
+ matrix->e,
+ matrix->f));
+ CGContextSetTextMatrix(context, m);
+ }
+ FX_INT32 a, r, g, b;
+ ArgbDecode(argb, a, r, g, b);
+ CGContextSetRGBFillColor(context,
+ r / 255.f,
+ g / 255.f,
+ b / 255.f,
+ a / 255.f);
+ CGContextSaveGState(context);
+#if CGFLOAT_IS_DOUBLE
+ CGPoint* glyphPositionsCG = new CGPoint[charsCount];
+ if (!glyphPositionsCG) {
+ return FALSE;
+ }
+ for (int index = 0; index < charsCount; ++index) {
+ glyphPositionsCG[index].x = glyphPositions[index].x;
+ glyphPositionsCG[index].y = glyphPositions[index].y;
+ }
+#else
+ CGPoint* glyphPositionsCG = (CGPoint*)glyphPositions;
+#endif
+ CGContextShowGlyphsAtPositions(context,
+ (CGGlyph *) glyphIndices,
+ glyphPositionsCG,
+ charsCount);
+#if CGFLOAT_IS_DOUBLE
+ delete[] glyphPositionsCG;
+#endif
+ CGContextRestoreGState(context);
+ return TRUE;
+}
+void CQuartz2D::saveGraphicsState(void * graphics)
+{
+ if (graphics) {
+ CGContextSaveGState((CGContextRef) graphics);
+ }
+}
+void CQuartz2D::restoreGraphicsState(void * graphics)
+{
+ if (graphics) {
+ CGContextRestoreGState((CGContextRef) graphics);
+ }
+}
+static CGContextRef createContextWithBitmap(CFX_DIBitmap* pBitmap)
+{
+ if (!pBitmap || pBitmap->IsCmykImage() || pBitmap->GetBPP() < 32) {
+ return NULL;
+ }
+ CGBitmapInfo bitmapInfo = kCGBitmapByteOrder32Little;
+ if (pBitmap->HasAlpha()) {
+ bitmapInfo |= kCGImageAlphaPremultipliedFirst;
+ } else {
+ bitmapInfo |= kCGImageAlphaNoneSkipFirst;
+ }
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
+ CGContextRef context = CGBitmapContextCreate(pBitmap->GetBuffer(),
+ pBitmap->GetWidth(),
+ pBitmap->GetHeight(),
+ 8,
+ pBitmap->GetPitch(),
+ colorSpace,
+ bitmapInfo);
+ CGColorSpaceRelease(colorSpace);
+ return context;
+}
+CFX_QuartzDeviceDriver::CFX_QuartzDeviceDriver(CGContextRef context, FX_INT32 deviceClass)
+{
+ m_saveCount = 0;
+ _context = context;
+ _deviceClass = deviceClass;
+ CGContextRetain(_context);
+ CGRect r = CGContextGetClipBoundingBox(context);
+ _width = FXSYS_round(r.size.width);
+ _height = FXSYS_round(r.size.height);
+ _renderCaps = FXRC_SOFT_CLIP | FXRC_BLEND_MODE |
+ FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE |
+ FXRC_BIT_MASK | FXRC_ALPHA_MASK;
+ if (_deviceClass != FXDC_DISPLAY) {
+ } else {
+ CGImageRef image = CGBitmapContextCreateImage(_context);
+ if (image) {
+ _renderCaps |= FXRC_GET_BITS;
+ _width = CGImageGetWidth(image);
+ _height = CGImageGetHeight(image);
+ CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(image);
+ if (kCGImageAlphaPremultipliedFirst == alphaInfo ||
+ kCGImageAlphaPremultipliedLast == alphaInfo ||
+ kCGImageAlphaOnly == alphaInfo) {
+ _renderCaps |= FXRC_ALPHA_OUTPUT;
+ }
+ }
+ CGImageRelease(image);
+ }
+ CGAffineTransform ctm = CGContextGetCTM(_context);
+ CGContextSaveGState(_context);
+ m_saveCount++;
+ if (ctm.d >= 0) {
+ CGFloat offset_x, offset_y;
+ offset_x = ctm.tx;
+ offset_y = ctm.ty;
+ CGContextTranslateCTM(_context, -offset_x, -offset_y);
+ CGContextConcatCTM(_context, CGAffineTransformMake(1, 0, 0, -1, offset_x, _height + offset_y));
+ }
+ _foxitDevice2User = CGAffineTransformIdentity;
+ _user2FoxitDevice = CGAffineTransformInvert(_foxitDevice2User);
+}
+CFX_QuartzDeviceDriver::~CFX_QuartzDeviceDriver()
+{
+ CGContextRestoreGState(_context);
+ m_saveCount--;
+ for (int i = 0; i < m_saveCount; ++i) {
+ CGContextRestoreGState(_context);
+ }
+ if (_context) {
+ CGContextRelease(_context);
+ }
+}
+int CFX_QuartzDeviceDriver::GetDeviceCaps(int capsID)
+{
+ switch (capsID) {
+ case FXDC_DEVICE_CLASS: {
+ return _deviceClass;
+ }
+ case FXDC_PIXEL_WIDTH: {
+ return _width;
+ }
+ case FXDC_PIXEL_HEIGHT: {
+ return _height;
+ }
+ case FXDC_BITS_PIXEL: {
+ return 32;
+ }
+ case FXDC_RENDER_CAPS: {
+ return _renderCaps;
+ }
+ default: {
+ return 0;
+ }
+ }
+}
+CFX_Matrix CFX_QuartzDeviceDriver::GetCTM() const
+{
+ CGAffineTransform ctm = CGContextGetCTM(_context);
+ return CFX_Matrix(ctm.a, ctm.b, ctm.c, ctm.d, ctm.tx, ctm.ty);
+}
+void CFX_QuartzDeviceDriver::SaveState()
+{
+ CGContextSaveGState(_context);
+ m_saveCount++;
+}
+void CFX_QuartzDeviceDriver::RestoreState(FX_BOOL isKeepSaved )
+{
+ CGContextRestoreGState(_context);
+ if (isKeepSaved) {
+ CGContextSaveGState(_context);
+ } else {
+ m_saveCount--;
+ }
+}
+FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathFill(const CFX_PathData* pathData,
+ const CFX_AffineMatrix* matrix,
+ int fillMode )
+{
+ SaveState();
+ CGAffineTransform m = CGAffineTransformIdentity;
+ if (matrix) {
+ m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF());
+ }
+ m = CGAffineTransformConcat(m, _foxitDevice2User);
+ CGContextConcatCTM(_context, m);
+ setPathToContext(pathData);
+ RestoreState(FALSE);
+ if ((fillMode & 3) == FXFILL_WINDING) {
+ CGContextClip(_context);
+ } else {
+ CGContextEOClip(_context);
+ }
+ return TRUE;
+}
+FX_FLOAT CFX_QuartzDeviceDriver::getLineWidth(const CFX_GraphStateData * graphState, CGAffineTransform ctm)
+{
+ FX_FLOAT lineWidth = graphState->m_LineWidth;
+ if (graphState->m_LineWidth <= 0.f) {
+ CGSize size;
+ size.width = 1;
+ size.height = 1;
+ CGSize temp = CGSizeApplyAffineTransform(size, ctm);
+ CGFloat x = 1 / temp.width;
+ CGFloat y = 1 / temp.height;
+ lineWidth = x > y ? x : y;
+ }
+ return lineWidth;
+}
+FX_BOOL CFX_QuartzDeviceDriver::SetClip_PathStroke(const CFX_PathData* pathData,
+ const CFX_AffineMatrix* matrix,
+ const CFX_GraphStateData* graphState )
+{
+ SaveState();
+ CGAffineTransform m = CGAffineTransformIdentity;
+ if (matrix) {
+ m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF());
+ }
+ m = CGAffineTransformConcat(m, _foxitDevice2User);
+ CGContextConcatCTM(_context, m);
+ FX_FLOAT lineWidth = getLineWidth(graphState, m);
+ setStrokeInfo(graphState, 0xFF000000, lineWidth);
+ setPathToContext(pathData);
+ CGContextReplacePathWithStrokedPath(_context);
+ RestoreState(FALSE);
+ CGContextClip(_context);
+ return TRUE;
+}
+static CGBlendMode GetCGBlendMode(int blend_type)
+{
+ CGBlendMode mode = kCGBlendModeNormal;
+ switch (blend_type) {
+ case FXDIB_BLEND_NORMAL:
+ mode = kCGBlendModeNormal;
+ break;
+ case FXDIB_BLEND_MULTIPLY:
+ mode = kCGBlendModeMultiply;
+ break;
+ case FXDIB_BLEND_SCREEN:
+ mode = kCGBlendModeScreen;
+ break;
+ case FXDIB_BLEND_OVERLAY:
+ mode = kCGBlendModeOverlay;
+ break;
+ case FXDIB_BLEND_DARKEN:
+ mode = kCGBlendModeDarken;
+ break;
+ case FXDIB_BLEND_LIGHTEN:
+ mode = kCGBlendModeLighten;
+ break;
+ case FXDIB_BLEND_COLORDODGE:
+ mode = kCGBlendModeColorDodge;
+ break;
+ case FXDIB_BLEND_COLORBURN:
+ mode = kCGBlendModeColorBurn;
+ break;
+ case FXDIB_BLEND_HARDLIGHT:
+ mode = kCGBlendModeHardLight;
+ break;
+ case FXDIB_BLEND_SOFTLIGHT:
+ mode = kCGBlendModeSoftLight;
+ break;
+ case FXDIB_BLEND_DIFFERENCE:
+ mode = kCGBlendModeDifference;
+ break;
+ case FXDIB_BLEND_EXCLUSION:
+ mode = kCGBlendModeExclusion;
+ break;
+ case FXDIB_BLEND_HUE:
+ mode = kCGBlendModeHue;
+ break;
+ case FXDIB_BLEND_SATURATION:
+ mode = kCGBlendModeSaturation;
+ break;
+ case FXDIB_BLEND_COLOR:
+ mode = kCGBlendModeColor;
+ break;
+ case FXDIB_BLEND_LUMINOSITY:
+ mode = kCGBlendModeLuminosity;
+ break;
+ default:
+ mode = kCGBlendModeNormal;
+ break;
+ }
+ return mode;
+}
+FX_BOOL CFX_QuartzDeviceDriver::DrawPath(const CFX_PathData* pathData,
+ const CFX_AffineMatrix* matrix,
+ const CFX_GraphStateData* graphState,
+ FX_DWORD fillArgb,
+ FX_DWORD strokeArgb,
+ int fillMode,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type
+ )
+{
+ SaveState();
+ CGBlendMode mode = GetCGBlendMode(blend_type);
+ if (mode != kCGBlendModeNormal) {
+ CGContextSetBlendMode(_context, mode);
+ }
+ CGAffineTransform m = CGAffineTransformIdentity;
+ if (matrix) {
+ m = CGAffineTransformMake(matrix->GetA(), matrix->GetB(), matrix->GetC(), matrix->GetD(), matrix->GetE(), matrix->GetF());
+ }
+ m = CGAffineTransformConcat(m, _foxitDevice2User);
+ CGContextConcatCTM(_context, m);
+ int pathMode = 0;
+ if (graphState && strokeArgb) {
+ CGContextSetMiterLimit(_context, graphState->m_MiterLimit);
+ FX_FLOAT lineWidth = getLineWidth(graphState, m);
+ setStrokeInfo(graphState, strokeArgb, lineWidth);
+ pathMode |= 4;
+ }
+ if (fillMode && fillArgb) {
+ setFillInfo(fillArgb);
+ if ((fillMode & 3) == FXFILL_WINDING) {
+ pathMode |= 1;
+ } else if ((fillMode & 3) == FXFILL_ALTERNATE) {
+ pathMode |= 2;
+ }
+ }
+ setPathToContext(pathData);
+ if (fillMode & FXFILL_FULLCOVER) {
+ CGContextSetShouldAntialias(_context, false);
+ }
+ if (pathMode == 4) {
+ CGContextStrokePath(_context);
+ } else if (pathMode == 1) {
+ CGContextFillPath(_context);
+ } else if (pathMode == 2) {
+ CGContextEOFillPath(_context);
+ } else if (pathMode == 5) {
+ CGContextDrawPath(_context, kCGPathFillStroke);
+ } else if (pathMode == 6) {
+ CGContextDrawPath(_context, kCGPathEOFillStroke);
+ }
+ RestoreState(FALSE);
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDeviceDriver::FillRect(const FX_RECT* rect,
+ FX_ARGB fillArgb,
+ int alphaFlag ,
+ void* iccTransform ,
+ int blend_type )
+{
+ CGBlendMode mode = GetCGBlendMode(blend_type);
+ if (mode != kCGBlendModeNormal) {
+ CGContextSetBlendMode(_context, mode);
+ }
+ CGRect rect_fx = CGRectMake(rect->left, rect->top, rect->Width(), rect->Height());
+ CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
+ FX_INT32 a, r, g, b;
+ ArgbDecode(fillArgb, a, r, g, b);
+ CGContextSetRGBFillColor(_context,
+ r / 255.f,
+ g / 255.f,
+ b / 255.f,
+ a / 255.f);
+ CGContextFillRect(_context, rect_usr);
+ if (mode != kCGBlendModeNormal) {
+ CGContextSetBlendMode(_context, kCGBlendModeNormal);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDeviceDriver::DrawCosmeticLine(FX_FLOAT x1,
+ FX_FLOAT y1,
+ FX_FLOAT x2,
+ FX_FLOAT y2,
+ FX_DWORD argb,
+ int alphaFlag ,
+ void* iccTransform ,
+ int blend_type )
+{
+ CGBlendMode mode = GetCGBlendMode(blend_type);
+ if (mode != kCGBlendModeNormal) {
+ CGContextSetBlendMode(_context, mode);
+ }
+ CGPoint pt = CGPointApplyAffineTransform(CGPointMake(x1, y1), _foxitDevice2User);
+ x1 = pt.x;
+ y1 = pt.y;
+ pt = CGPointApplyAffineTransform(CGPointMake(x2, y2), _foxitDevice2User);
+ x2 = pt.x;
+ y2 = pt.y;
+ FX_INT32 a, r, g, b;
+ ArgbDecode(argb, a, r, g, b);
+ CGContextSetRGBStrokeColor(_context,
+ r / 255.f,
+ g / 255.f,
+ b / 255.f,
+ a / 255.f);
+ CGContextMoveToPoint(_context, x1, y1);
+ CGContextAddLineToPoint(_context, x2, y2);
+ CGContextStrokePath(_context);
+ if (mode != kCGBlendModeNormal) {
+ CGContextSetBlendMode(_context, kCGBlendModeNormal);
+ }
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDeviceDriver::GetClipBox(FX_RECT* rect)
+{
+ CGRect r = CGContextGetClipBoundingBox(_context);
+ r = CGRectApplyAffineTransform(r, _user2FoxitDevice);
+ rect->left = FXSYS_floor(r.origin.x);
+ rect->top = FXSYS_floor(r.origin.y);
+ rect->right = FXSYS_ceil(r.origin.x + r.size.width);
+ rect->bottom = FXSYS_ceil(r.origin.y + r.size.height);
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDeviceDriver::GetDIBits(CFX_DIBitmap* bitmap,
+ FX_INT32 left,
+ FX_INT32 top,
+ void* pIccTransform,
+ FX_BOOL bDEdge)
+{
+ if (FXDC_PRINTER == _deviceClass) {
+ return FALSE;
+ }
+ if (bitmap->GetBPP() < 32) {
+ return FALSE;
+ }
+ if (!(_renderCaps | FXRC_GET_BITS)) {
+ return FALSE;
+ }
+ CGPoint pt = CGPointMake(left, top);
+ pt = CGPointApplyAffineTransform(pt, _foxitDevice2User);
+ CGAffineTransform ctm = CGContextGetCTM(_context);
+ pt.x *= FXSYS_fabs(ctm.a);
+ pt.y *= FXSYS_fabs(ctm.d);
+ CGImageRef image = CGBitmapContextCreateImage(_context);
+ if (NULL == image) {
+ return FALSE;
+ }
+ CGFloat width = (CGFloat) bitmap->GetWidth();
+ CGFloat height = (CGFloat) bitmap->GetHeight();
+ if (width + pt.x > _width) {
+ width -= (width + pt.x - _width);
+ }
+ if (height + pt.y > _height) {
+ height -= (height + pt.y - _height);
+ }
+ CGImageRef subImage = CGImageCreateWithImageInRect(image,
+ CGRectMake(pt.x,
+ pt.y,
+ width,
+ height));
+ CGContextRef context = createContextWithBitmap(bitmap);
+ CGRect rect = CGContextGetClipBoundingBox(context);
+ CGContextClearRect(context, rect);
+ CGContextDrawImage(context, rect, subImage);
+ CGContextRelease(context);
+ CGImageRelease(subImage);
+ CGImageRelease(image);
+ if (bitmap->HasAlpha()) {
+ for (int row = 0; row < bitmap->GetHeight(); row ++) {
+ FX_LPBYTE pScanline = (FX_LPBYTE)bitmap->GetScanline(row);
+ for (int col = 0; col < bitmap->GetWidth(); col ++) {
+ if (pScanline[3] > 0) {
+ pScanline[0] = (pScanline[0] * 255.f / pScanline[3] + .5f);
+ pScanline[1] = (pScanline[1] * 255.f / pScanline[3] + .5f);
+ pScanline[2] = (pScanline[2] * 255.f / pScanline[3] + .5f);
+ }
+ pScanline += 4;
+ }
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap,
+ FX_ARGB argb,
+ const FX_RECT* srcRect,
+ int dest_left,
+ int dest_top,
+ int blendType,
+ int alphaFlag ,
+ void* iccTransform )
+{
+ SaveState();
+ CGFloat src_left, src_top, src_width, src_height;
+ if (srcRect) {
+ src_left = srcRect->left;
+ src_top = srcRect->top;
+ src_width = srcRect->Width();
+ src_height = srcRect->Height();
+ } else {
+ src_left = src_top = 0;
+ src_width = pBitmap->GetWidth();
+ src_height = pBitmap->GetHeight();
+ }
+ CGAffineTransform ctm = CGContextGetCTM(_context);
+ CGFloat scale_x = FXSYS_fabs(ctm.a);
+ CGFloat scale_y = FXSYS_fabs(ctm.d);
+ src_left /= scale_x;
+ src_top /= scale_y;
+ src_width /= scale_x;
+ src_height /= scale_y;
+ CGRect rect_fx = CGRectMake(dest_left, dest_top, src_width, src_height);
+ CGRect rect_usr = CGRectApplyAffineTransform(rect_fx, _foxitDevice2User);
+ CGContextBeginPath(_context);
+ CGContextAddRect(_context, rect_usr);
+ CGContextClip(_context);
+ rect_usr.size = CGSizeMake(pBitmap->GetWidth() / scale_x, pBitmap->GetHeight() / scale_y);
+ rect_usr = CGRectOffset(rect_usr, -src_left, -src_top);
+ CG_SetImageTransform(dest_left, dest_top, src_width, src_height, &rect_usr);
+ CFX_DIBitmap* pBitmap1 = NULL;
+ if (pBitmap->IsAlphaMask()) {
+ if (pBitmap->GetBuffer()) {
+ pBitmap1 = (CFX_DIBitmap*)pBitmap;
+ } else {
+ pBitmap1 = pBitmap->Clone();
+ }
+ if (NULL == pBitmap1) {
+ RestoreState(FALSE);
+ return FALSE;
+ }
+ CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
+ pBitmap1->GetBuffer(),
+ pBitmap1->GetPitch() * pBitmap1->GetHeight(),
+ NULL);
+ CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
+ CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
+ CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
+ pBitmap1->GetHeight(),
+ pBitmap1->GetBPP(),
+ pBitmap1->GetBPP(),
+ pBitmap1->GetPitch(),
+ pColorSpace,
+ bitmapInfo,
+ pBitmapProvider, NULL, true,
+ kCGRenderingIntentDefault);
+ CGContextClipToMask(_context, rect_usr, pImage);
+ CGContextSetRGBFillColor(_context,
+ FXARGB_R(argb) / 255.f,
+ FXARGB_G(argb) / 255.f,
+ FXARGB_B(argb) / 255.f,
+ FXARGB_A(argb) / 255.f);
+ CGContextFillRect(_context, rect_usr);
+ CGImageRelease(pImage);
+ CGColorSpaceRelease(pColorSpace);
+ CGDataProviderRelease(pBitmapProvider);
+ if (pBitmap1 != pBitmap) {
+ delete pBitmap1;
+ }
+ RestoreState(FALSE);
+ return TRUE;
+ }
+ if (pBitmap->GetBPP() < 32) {
+ pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
+ } else {
+ if (pBitmap->GetBuffer()) {
+ pBitmap1 = (CFX_DIBitmap*)pBitmap;
+ } else {
+ pBitmap1 = pBitmap->Clone();
+ }
+ }
+ if (NULL == pBitmap1) {
+ RestoreState(FALSE);
+ return FALSE;
+ }
+ if (pBitmap1->HasAlpha()) {
+ if (pBitmap1 == pBitmap) {
+ pBitmap1 = pBitmap->Clone();
+ if (!pBitmap1) {
+ RestoreState(FALSE);
+ return FALSE;
+ }
+ }
+ for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
+ FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
+ for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
+ pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
+ pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
+ pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
+ pScanline += 4;
+ }
+ }
+ }
+ CGContextRef ctx = createContextWithBitmap(pBitmap1);
+ CGImageRef image = CGBitmapContextCreateImage(ctx);
+ int blend_mode = blendType;
+ if (FXDIB_BLEND_HARDLIGHT == blendType) {
+ blend_mode = kCGBlendModeSoftLight;
+ } else if (FXDIB_BLEND_SOFTLIGHT == blendType) {
+ blend_mode = kCGBlendModeHardLight;
+ } else if (blendType >= FXDIB_BLEND_NONSEPARABLE && blendType <= FXDIB_BLEND_LUMINOSITY) {
+ blend_mode = blendType - 9;
+ } else if (blendType > FXDIB_BLEND_LUMINOSITY || blendType < 0) {
+ blend_mode = kCGBlendModeNormal;
+ }
+ CGContextSetBlendMode(_context, (CGBlendMode)blend_mode);
+ CGContextDrawImage(_context, rect_usr, image);
+ CGImageRelease(image);
+ CGContextRelease(ctx);
+ if (pBitmap1 != pBitmap) {
+ delete pBitmap1;
+ }
+ RestoreState(FALSE);
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDeviceDriver::StretchDIBits(const CFX_DIBSource* pBitmap,
+ FX_ARGB argb,
+ int dest_left,
+ int dest_top,
+ int dest_width,
+ int dest_height,
+ const FX_RECT* clipRect,
+ FX_DWORD flags,
+ int alphaFlag ,
+ void* iccTransform ,
+ int blend_type)
+{
+ SaveState();
+ if (clipRect) {
+ CGContextBeginPath(_context);
+ CGRect rect_clip = CGRectMake(clipRect->left, clipRect->top, clipRect->Width(), clipRect->Height());
+ rect_clip = CGRectApplyAffineTransform(rect_clip, _foxitDevice2User);
+ CGContextAddRect(_context, rect_clip);
+ CGContextClip(_context);
+ }
+ CGRect rect = CGRectMake(dest_left, dest_top, dest_width, dest_height);
+ rect = CGRectApplyAffineTransform(rect, _foxitDevice2User);
+ if (FXDIB_BICUBIC_INTERPOL == flags) {
+ CGContextSetInterpolationQuality(_context, kCGInterpolationHigh);
+ } else if (FXDIB_DOWNSAMPLE == flags) {
+ CGContextSetInterpolationQuality(_context, kCGInterpolationNone);
+ } else {
+ CGContextSetInterpolationQuality(_context, kCGInterpolationMedium);
+ }
+ CG_SetImageTransform(dest_left, dest_top, dest_width, dest_height);
+ CFX_DIBitmap* pBitmap1 = NULL;
+ if (pBitmap->IsAlphaMask()) {
+ if (pBitmap->GetBuffer()) {
+ pBitmap1 = (CFX_DIBitmap*)pBitmap;
+ } else {
+ pBitmap1 = pBitmap->Clone();
+ }
+ if (NULL == pBitmap1) {
+ RestoreState(FALSE);
+ return FALSE;
+ }
+ CGDataProviderRef pBitmapProvider = CGDataProviderCreateWithData(NULL,
+ pBitmap1->GetBuffer(),
+ pBitmap1->GetPitch() * pBitmap1->GetHeight(),
+ NULL);
+ CGColorSpaceRef pColorSpace = CGColorSpaceCreateDeviceGray();
+ CGBitmapInfo bitmapInfo = kCGImageAlphaNone | kCGBitmapByteOrderDefault;
+ CGImageRef pImage = CGImageCreate(pBitmap1->GetWidth(),
+ pBitmap1->GetHeight(),
+ pBitmap1->GetBPP(),
+ pBitmap1->GetBPP(),
+ pBitmap1->GetPitch(),
+ pColorSpace,
+ bitmapInfo,
+ pBitmapProvider, NULL, true,
+ kCGRenderingIntentDefault);
+ CGContextClipToMask(_context, rect, pImage);
+ CGContextSetRGBFillColor(_context,
+ FXARGB_R(argb) / 255.f,
+ FXARGB_G(argb) / 255.f,
+ FXARGB_B(argb) / 255.f,
+ FXARGB_A(argb) / 255.f);
+ CGContextFillRect(_context, rect);
+ CGImageRelease(pImage);
+ CGColorSpaceRelease(pColorSpace);
+ CGDataProviderRelease(pBitmapProvider);
+ if (pBitmap1 != pBitmap) {
+ delete pBitmap1;
+ }
+ RestoreState(FALSE);
+ return TRUE;
+ }
+ if (pBitmap->GetBPP() < 32) {
+ pBitmap1 = pBitmap->CloneConvert(FXDIB_Rgb32);
+ } else {
+ if (pBitmap->GetBuffer()) {
+ pBitmap1 = (CFX_DIBitmap*)pBitmap;
+ } else {
+ pBitmap1 = pBitmap->Clone();
+ }
+ }
+ if (NULL == pBitmap1) {
+ RestoreState(FALSE);
+ return FALSE;
+ }
+ if (pBitmap1->HasAlpha()) {
+ if (pBitmap1 == pBitmap) {
+ pBitmap1 = pBitmap->Clone();
+ if (!pBitmap1) {
+ RestoreState(FALSE);
+ return FALSE;
+ }
+ }
+ for (int row = 0; row < pBitmap1->GetHeight(); row ++) {
+ FX_LPBYTE pScanline = (FX_LPBYTE)pBitmap1->GetScanline(row);
+ for (int col = 0; col < pBitmap1->GetWidth(); col ++) {
+ pScanline[0] = (FX_BYTE)(pScanline[0] * pScanline[3] / 255.f + .5f);
+ pScanline[1] = (FX_BYTE)(pScanline[1] * pScanline[3] / 255.f + .5f);
+ pScanline[2] = (FX_BYTE)(pScanline[2] * pScanline[3] / 255.f + .5f);
+ pScanline += 4;
+ }
+ }
+ }
+ CGContextRef ctx = createContextWithBitmap(pBitmap1);
+ CGImageRef image = CGBitmapContextCreateImage(ctx);
+ CGContextDrawImage(_context, rect, image);
+ CGImageRelease(image);
+ CGContextRelease(ctx);
+ if (pBitmap1 != pBitmap) {
+ delete pBitmap1;
+ }
+ RestoreState(FALSE);
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDeviceDriver::CG_DrawGlypRun(int nChars,
+ const FXTEXT_CHARPOS* pCharPos,
+ CFX_Font* pFont,
+ CFX_FontCache* pCache,
+ const CFX_AffineMatrix* pGlyphMatrix,
+ const CFX_AffineMatrix* pObject2Device,
+ FX_FLOAT font_size,
+ FX_DWORD argb,
+ int alpha_flag,
+ void* pIccTransform)
+{
+ if (nChars == 0) {
+ return TRUE;
+ }
+ CQuartz2D& quartz2d = ((CApplePlatform *) CFX_GEModule::Get()->GetPlatformData())->_quartz2d;
+ if (!pFont->m_pPlatformFont) {
+ if (pFont->GetPsName() == CFX_WideString::FromLocal("DFHeiStd-W5")) {
+ return FALSE;
+ }
+ pFont->m_pPlatformFont = quartz2d.CreateFont(pFont->m_pFontData, pFont->m_dwSize);
+ if (NULL == pFont->m_pPlatformFont) {
+ return FALSE;
+ }
+ }
+ CFX_FixedBufGrow<FX_WORD, 32> glyph_indices(nChars);
+ CFX_FixedBufGrow<CGPoint, 32> glyph_positions(nChars);
+ for (int i = 0; i < nChars; i++ ) {
+ glyph_indices[i] = pCharPos[i].m_ExtGID;
+ glyph_positions[i].x = pCharPos[i].m_OriginX;
+ glyph_positions[i].y = pCharPos[i].m_OriginY;
+ }
+ CFX_AffineMatrix text_matrix;
+ if (pObject2Device) {
+ text_matrix.Concat(*pObject2Device);
+ }
+ CGAffineTransform matrix_cg = CGAffineTransformMake(text_matrix.a,
+ text_matrix.b,
+ text_matrix.c,
+ text_matrix.d,
+ text_matrix.e,
+ text_matrix.f);
+ matrix_cg = CGAffineTransformConcat(matrix_cg, _foxitDevice2User);
+ CGContextSetTextMatrix(_context, matrix_cg);
+ CGContextSetFont(_context, (CGFontRef)pFont->m_pPlatformFont);
+ CGContextSetFontSize(_context, FXSYS_fabs(font_size));
+ FX_INT32 a, r, g, b;
+ ArgbDecode(argb, a, r, g, b);
+ CGContextSetRGBFillColor(_context,
+ r / 255.f,
+ g / 255.f,
+ b / 255.f,
+ a / 255.f);
+ SaveState();
+ if (pGlyphMatrix) {
+ CGAffineTransform ctm = CGContextGetCTM(_context);
+ CGPoint origin = CGPointMake( glyph_positions[0].x, glyph_positions[0].y);
+ origin = CGPointApplyAffineTransform(origin, matrix_cg);
+ CGContextTranslateCTM(_context, origin.x, origin.y);
+ CGAffineTransform glyph_matrix = CGAffineTransformMake(pGlyphMatrix->a,
+ pGlyphMatrix->b,
+ pGlyphMatrix->c,
+ pGlyphMatrix->d,
+ pGlyphMatrix->e,
+ pGlyphMatrix->f);
+ if (_foxitDevice2User.d < 0) {
+ glyph_matrix = CGAffineTransformInvert(glyph_matrix);
+ }
+ CGContextConcatCTM(_context, glyph_matrix);
+ CGContextTranslateCTM(_context, -origin.x, -origin.y);
+ }
+ CGContextShowGlyphsAtPositions(_context,
+ (CGGlyph*)glyph_indices,
+ glyph_positions,
+ nChars);
+ RestoreState(FALSE);
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDeviceDriver::DrawDeviceText(int nChars,
+ const FXTEXT_CHARPOS* pCharPos,
+ CFX_Font* pFont,
+ CFX_FontCache* pCache,
+ const CFX_AffineMatrix* pObject2Device,
+ FX_FLOAT font_size,
+ FX_DWORD color,
+ int alpha_flag ,
+ void* pIccTransform)
+{
+ if (NULL == pFont || NULL == _context) {
+ return FALSE;
+ }
+ FX_BOOL bBold = pFont->IsBold();
+ if (!bBold && pFont->GetSubstFont() &&
+ pFont->GetSubstFont()->m_Weight >= 500 &&
+ pFont->GetSubstFont()->m_Weight <= 600) {
+ return FALSE;
+ }
+ SaveState();
+ CGContextSetTextDrawingMode(_context, kCGTextFillClip);
+ FX_BOOL ret = FALSE;
+ FX_INT32 i = 0;
+ while (i < nChars) {
+ if (pCharPos[i].m_bGlyphAdjust || font_size < 0) {
+ if (i > 0) {
+ ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform);
+ if (!ret) {
+ RestoreState(FALSE);
+ return ret;
+ }
+ }
+ const FXTEXT_CHARPOS* char_pos = pCharPos + i;
+ CFX_AffineMatrix glphy_matrix;
+ if (font_size < 0) {
+ glphy_matrix.Concat(-1, 0, 0, -1, 0, 0);
+ }
+ if (char_pos->m_bGlyphAdjust) {
+ glphy_matrix.Concat(char_pos->m_AdjustMatrix[0],
+ char_pos->m_AdjustMatrix[1],
+ char_pos->m_AdjustMatrix[2],
+ char_pos->m_AdjustMatrix[3], 0, 0);
+ }
+ ret = CG_DrawGlypRun(1, char_pos, pFont, pCache, &glphy_matrix, pObject2Device, font_size, color, alpha_flag, pIccTransform);
+ if (!ret) {
+ RestoreState(FALSE);
+ return ret;
+ }
+ i ++;
+ pCharPos += i;
+ nChars -= i;
+ i = 0;
+ } else {
+ i ++;
+ }
+ }
+ if (i > 0) {
+ ret = CG_DrawGlypRun(i, pCharPos, pFont, pCache, NULL, pObject2Device, font_size, color, alpha_flag, pIccTransform);
+ }
+ RestoreState(FALSE);
+ return ret;
+}
+void CFX_QuartzDeviceDriver::setStrokeInfo(const CFX_GraphStateData* graphState, FX_ARGB argb, FX_FLOAT lineWidth)
+{
+ if (NULL == graphState) {
+ return;
+ }
+ CGContextSetLineWidth(_context, lineWidth);
+ CGLineCap cap;
+ switch (graphState->m_LineCap) {
+ case CFX_GraphStateData::LineCapRound: {
+ cap = kCGLineCapRound;
+ break;
+ }
+ case CFX_GraphStateData::LineCapSquare: {
+ cap = kCGLineCapSquare;
+ break;
+ }
+ case CFX_GraphStateData::LineCapButt:
+ default: {
+ cap = kCGLineCapButt;
+ }
+ }
+ CGContextSetLineCap(_context, cap);
+ CGLineJoin join;
+ switch (graphState->m_LineJoin) {
+ case CFX_GraphStateData::LineJoinRound: {
+ join = kCGLineJoinRound;
+ break;
+ }
+ case CFX_GraphStateData::LineJoinBevel: {
+ join = kCGLineJoinBevel;
+ break;
+ }
+ case CFX_GraphStateData::LineJoinMiter:
+ default: {
+ join = kCGLineJoinMiter;
+ }
+ }
+ CGContextSetLineJoin(_context, join);
+ if (graphState->m_DashCount) {
+#if CGFLOAT_IS_DOUBLE
+ CGFloat* dashArray = new CGFloat[graphState->m_DashCount];
+ if (!dashArray) {
+ return;
+ }
+ for (int index = 0; index < graphState->m_DashCount; ++index) {
+ dashArray[index] = graphState->m_DashArray[index];
+ }
+#else
+ CGFloat* dashArray = (CGFloat*)graphState->m_DashArray;
+#endif
+ CGContextSetLineDash(_context, graphState->m_DashPhase, dashArray, graphState->m_DashCount);
+#if CGFLOAT_IS_DOUBLE
+ delete[] dashArray;
+#endif
+ }
+ FX_INT32 a, r, g, b;
+ ArgbDecode(argb, a, r, g, b);
+ CGContextSetRGBStrokeColor(_context,
+ r / 255.f,
+ g / 255.f,
+ b / 255.f,
+ a / 255.f);
+}
+void CFX_QuartzDeviceDriver::setFillInfo(FX_ARGB argb)
+{
+ FX_INT32 a, r, g, b;
+ ArgbDecode(argb, a, r, g, b);
+ CGContextSetRGBFillColor(_context,
+ r / 255.f,
+ g / 255.f,
+ b / 255.f,
+ a / 255.f);
+}
+void CFX_QuartzDeviceDriver::setPathToContext(const CFX_PathData* pathData)
+{
+ FX_INT32 count = pathData->GetPointCount();
+ FX_PATHPOINT* points = pathData->GetPoints();
+ CGContextBeginPath(_context);
+ for (FX_INT32 i = 0; i < count; i ++) {
+ switch (points[i].m_Flag & FXPT_TYPE) {
+ case FXPT_MOVETO:
+ CGContextMoveToPoint(_context, points[i].m_PointX, points[i].m_PointY);
+ break;
+ case FXPT_LINETO:
+ CGContextAddLineToPoint(_context, points[i].m_PointX, points[i].m_PointY);
+ break;
+ case FXPT_BEZIERTO: {
+ CGContextAddCurveToPoint(_context,
+ points[i].m_PointX, points[i].m_PointY,
+ points[i + 1].m_PointX, points[i + 1].m_PointY,
+ points[i + 2].m_PointX, points[i + 2].m_PointY);
+ i += 2;
+ }
+ }
+ if (points[i].m_Flag & FXPT_CLOSEFIGURE) {
+ CGContextClosePath(_context);
+ }
+ }
+}
+void CFX_QuartzDeviceDriver::CG_SetImageTransform(int dest_left, int dest_top, int dest_width, int dest_height,
+ CGRect* rect )
+{
+ int flip_y = _foxitDevice2User.d * dest_height < 0 ? 1 : -1;
+ int flip_x = _foxitDevice2User.a * dest_width > 0 ? 1 : -1;
+ if (flip_y < 0 || flip_x < 0) {
+ if (dest_height < 0) {
+ dest_height = -dest_height;
+ dest_top -= dest_height;
+ }
+ CGRect rt = CGRectApplyAffineTransform(CGRectMake(dest_left, dest_top, dest_width, dest_height), _foxitDevice2User);
+ CGFloat offset_x = (rt.origin.x) + rt.size.width / 2.f,
+ offset_y = (rt.origin.y) + rt.size.height / 2.f;
+ CGAffineTransform transform = CGAffineTransformIdentity;
+ transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, -offset_x, -offset_y));
+ transform = CGAffineTransformConcat(transform, CGAffineTransformMake(flip_x, 0, 0, flip_y, 0, 0));
+ transform = CGAffineTransformConcat(transform, CGAffineTransformMake(1, 0, 0, 1, offset_x, offset_y));
+ CGContextConcatCTM(_context, transform);
+ if (rect) {
+ *rect = CGRectApplyAffineTransform(*rect, transform);
+ }
+ }
+}
+void CFX_QuartzDeviceDriver::ClearDriver()
+{
+ if (NULL == _context) {
+ return;
+ }
+ for (int i = 0; i < m_saveCount; ++i) {
+ CGContextRestoreGState(_context);
+ }
+ m_saveCount = 0;
+ if (_context) {
+ CGContextRelease(_context);
+ }
+}
+CFX_QuartzDevice::CFX_QuartzDevice()
+{
+ m_bOwnedBitmap = FALSE;
+ m_pContext = NULL;
+}
+CFX_QuartzDevice::~CFX_QuartzDevice()
+{
+ if (m_pContext) {
+ CGContextRelease(m_pContext);
+ }
+ if (GetBitmap() && m_bOwnedBitmap) {
+ delete GetBitmap();
+ }
+}
+CGContextRef CFX_QuartzDevice::GetContext()
+{
+ return m_pContext;
+}
+FX_BOOL CFX_QuartzDevice::Attach(CGContextRef context, FX_INT32 nDeviceClass)
+{
+ if (m_pContext) {
+ CGContextRelease(m_pContext);
+ }
+ m_pContext = context;
+ CGContextRetain(m_pContext);
+ IFX_RenderDeviceDriver* pDriver = FX_NEW CFX_QuartzDeviceDriver(m_pContext, nDeviceClass);
+ if (!pDriver) {
+ return FALSE;
+ }
+ SetDeviceDriver(pDriver);
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDevice::Attach(CFX_DIBitmap* pBitmap)
+{
+ SetBitmap(pBitmap);
+ m_pContext = createContextWithBitmap(pBitmap);
+ if (NULL == m_pContext) {
+ return FALSE;
+ }
+ IFX_RenderDeviceDriver* pDriver = FX_NEW CFX_QuartzDeviceDriver(m_pContext, FXDC_DISPLAY);
+ if (!pDriver) {
+ return FALSE;
+ }
+ SetDeviceDriver(pDriver);
+ return TRUE;
+}
+FX_BOOL CFX_QuartzDevice::Create(FX_INT32 width, FX_INT32 height, FXDIB_Format format)
+{
+ if ((FX_BYTE)format < 32) {
+ return FALSE;
+ }
+ CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
+ if (!pBitmap) {
+ return FALSE;
+ }
+ if (!pBitmap->Create(width, height, format)) {
+ delete pBitmap;
+ return FALSE;
+ }
+ m_bOwnedBitmap = TRUE;
+ return Attach(pBitmap);
+}
+#endif
diff --git a/core/src/fxge/dib/dib_int.h b/core/src/fxge/dib/dib_int.h
index a9d0b027c5..1e6d82ea86 100644
--- a/core/src/fxge/dib/dib_int.h
+++ b/core/src/fxge/dib/dib_int.h
@@ -1,88 +1,88 @@
-// 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
-
-class CPDF_FixedMatrix : public CFX_Object
-{
-public:
- CPDF_FixedMatrix(const CFX_AffineMatrix& src, int bits)
- {
- base = 1 << bits;
- a = FXSYS_round(src.a * base);
- b = FXSYS_round(src.b * base);
- c = FXSYS_round(src.c * base);
- d = FXSYS_round(src.d * base);
- e = FXSYS_round(src.e * base);
- f = FXSYS_round(src.f * base);
- }
- inline void Transform(int x, int y, int& x1, int& y1)
- {
- x1 = (a * x + c * y + e + base / 2) / base;
- y1 = (b * x + d * y + f + base / 2) / base;
- }
- int a, b, c, d, e, f;
- int base;
-};
-#define FPDF_HUGE_IMAGE_SIZE 60000000
-struct PixelWeight {
- int m_SrcStart;
- int m_SrcEnd;
- int m_Weights[1];
-};
-class CWeightTable : public CFX_Object
-{
-public:
- CWeightTable()
- {
- m_pWeightTables = NULL;
- }
- ~CWeightTable()
- {
- if(m_pWeightTables) {
- FX_Free(m_pWeightTables);
- }
- m_pWeightTables = NULL;
- }
- void Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, int flags);
- PixelWeight* GetPixelWeight(int pixel)
- {
- return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize);
- }
- int m_DestMin, m_ItemSize;
- FX_LPBYTE m_pWeightTables;
-};
-class CStretchEngine : public CFX_Object
-{
-public:
- CStretchEngine(IFX_ScanlineComposer* pDestBitmap, FXDIB_Format dest_format,
- int dest_width, int dest_height, const FX_RECT& clip_rect,
- const CFX_DIBSource* pSrcBitmap, int flags);
- ~CStretchEngine();
- FX_BOOL Continue(IFX_Pause* pPause);
-public:
- FXDIB_Format m_DestFormat;
- int m_DestBpp, m_SrcBpp, m_bHasAlpha;
- IFX_ScanlineComposer* m_pDestBitmap;
- int m_DestWidth, m_DestHeight;
- FX_RECT m_DestClip;
- FX_LPBYTE m_pDestScanline;
- FX_LPBYTE m_pDestMaskScanline;
- FX_RECT m_SrcClip;
- const CFX_DIBSource* m_pSource;
- FX_DWORD* m_pSrcPalette;
- int m_SrcWidth, m_SrcHeight;
- int m_SrcPitch, m_InterPitch;
- int m_ExtraMaskPitch;
- unsigned char* m_pInterBuf;
- unsigned char* m_pExtraAlphaBuf;
- int m_TransMethod;
- int m_Flags;
- CWeightTable m_WeightTable;
- int m_CurRow;
- FX_BOOL StartStretchHorz();
- FX_BOOL ContinueStretchHorz(IFX_Pause* pPause);
- void StretchVert();
- int m_State;
-};
+// 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
+
+class CPDF_FixedMatrix : public CFX_Object
+{
+public:
+ CPDF_FixedMatrix(const CFX_AffineMatrix& src, int bits)
+ {
+ base = 1 << bits;
+ a = FXSYS_round(src.a * base);
+ b = FXSYS_round(src.b * base);
+ c = FXSYS_round(src.c * base);
+ d = FXSYS_round(src.d * base);
+ e = FXSYS_round(src.e * base);
+ f = FXSYS_round(src.f * base);
+ }
+ inline void Transform(int x, int y, int& x1, int& y1)
+ {
+ x1 = (a * x + c * y + e + base / 2) / base;
+ y1 = (b * x + d * y + f + base / 2) / base;
+ }
+ int a, b, c, d, e, f;
+ int base;
+};
+#define FPDF_HUGE_IMAGE_SIZE 60000000
+struct PixelWeight {
+ int m_SrcStart;
+ int m_SrcEnd;
+ int m_Weights[1];
+};
+class CWeightTable : public CFX_Object
+{
+public:
+ CWeightTable()
+ {
+ m_pWeightTables = NULL;
+ }
+ ~CWeightTable()
+ {
+ if(m_pWeightTables) {
+ FX_Free(m_pWeightTables);
+ }
+ m_pWeightTables = NULL;
+ }
+ void Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, int flags);
+ PixelWeight* GetPixelWeight(int pixel)
+ {
+ return (PixelWeight*)(m_pWeightTables + (pixel - m_DestMin) * m_ItemSize);
+ }
+ int m_DestMin, m_ItemSize;
+ FX_LPBYTE m_pWeightTables;
+};
+class CStretchEngine : public CFX_Object
+{
+public:
+ CStretchEngine(IFX_ScanlineComposer* pDestBitmap, FXDIB_Format dest_format,
+ int dest_width, int dest_height, const FX_RECT& clip_rect,
+ const CFX_DIBSource* pSrcBitmap, int flags);
+ ~CStretchEngine();
+ FX_BOOL Continue(IFX_Pause* pPause);
+public:
+ FXDIB_Format m_DestFormat;
+ int m_DestBpp, m_SrcBpp, m_bHasAlpha;
+ IFX_ScanlineComposer* m_pDestBitmap;
+ int m_DestWidth, m_DestHeight;
+ FX_RECT m_DestClip;
+ FX_LPBYTE m_pDestScanline;
+ FX_LPBYTE m_pDestMaskScanline;
+ FX_RECT m_SrcClip;
+ const CFX_DIBSource* m_pSource;
+ FX_DWORD* m_pSrcPalette;
+ int m_SrcWidth, m_SrcHeight;
+ int m_SrcPitch, m_InterPitch;
+ int m_ExtraMaskPitch;
+ unsigned char* m_pInterBuf;
+ unsigned char* m_pExtraAlphaBuf;
+ int m_TransMethod;
+ int m_Flags;
+ CWeightTable m_WeightTable;
+ int m_CurRow;
+ FX_BOOL StartStretchHorz();
+ FX_BOOL ContinueStretchHorz(IFX_Pause* pPause);
+ void StretchVert();
+ int m_State;
+};
diff --git a/core/src/fxge/dib/fx_dib_composite.cpp b/core/src/fxge/dib/fx_dib_composite.cpp
index 8e9b4912a8..1bbe07725b 100644
--- a/core/src/fxge/dib/fx_dib_composite.cpp
+++ b/core/src/fxge/dib/fx_dib_composite.cpp
@@ -1,4602 +1,4602 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#include "../../../include/fxcodec/fx_codec.h"
-#include "dib_int.h"
-const FX_BYTE g_GammaRamp[256] = {
- 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
- 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
- 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13,
- 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20,
- 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
- 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 37, 38, 39, 40, 41,
- 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
- 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88,
- 90, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109,
- 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 130, 131, 133,
- 134, 136, 138, 139, 141, 142, 144, 146, 147, 149, 151, 152, 154, 156, 157, 159,
- 161, 163, 164, 166, 168, 170, 171, 173, 175, 177, 179, 181, 183, 184, 186, 188,
- 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220,
- 222, 224, 226, 229, 231, 233, 235, 237, 239, 242, 244, 246, 248, 250, 253, 255,
-};
-const FX_BYTE g_GammaInverse[256] = {
- 0, 13, 22, 28, 34, 38, 42, 46, 50, 53, 56, 59, 61, 64, 66, 69,
- 71, 73, 75, 77, 79, 81, 83, 85, 86, 88, 90, 92, 93, 95, 96, 98,
- 99, 101, 102, 104, 105, 106, 108, 109, 110, 112, 113, 114, 115, 117, 118, 119,
- 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
- 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151,
- 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164,
- 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176,
- 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187,
- 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197,
- 198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207,
- 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216,
- 216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
- 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
- 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240,
- 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248,
- 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
-};
-const FX_BYTE _color_sqrt[256] = {
- 0x00, 0x03, 0x07, 0x0B, 0x0F, 0x12, 0x16, 0x19, 0x1D, 0x20, 0x23, 0x26, 0x29, 0x2C, 0x2F, 0x32,
- 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x41, 0x43, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56,
- 0x57, 0x59, 0x5B, 0x5C, 0x5E, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
- 0x6E, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
- 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
- 0x8F, 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C,
- 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8,
- 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4,
- 0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF,
- 0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xC9,
- 0xCA, 0xCB, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3,
- 0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD,
- 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6,
- 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE,
- 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7,
- 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF
-};
-int _BLEND(int blend_mode, int back_color, int src_color)
-{
- switch (blend_mode) {
- case FXDIB_BLEND_NORMAL:
- return src_color;
- case FXDIB_BLEND_MULTIPLY:
- return src_color * back_color / 255;
- case FXDIB_BLEND_SCREEN:
- return src_color + back_color - src_color * back_color / 255;
- case FXDIB_BLEND_OVERLAY:
- return _BLEND(FXDIB_BLEND_HARDLIGHT, src_color, back_color);
- case FXDIB_BLEND_DARKEN:
- return src_color < back_color ? src_color : back_color;
- case FXDIB_BLEND_LIGHTEN:
- return src_color > back_color ? src_color : back_color;
- case FXDIB_BLEND_COLORDODGE: {
- if (src_color == 255) {
- return src_color;
- }
- int result = back_color * 255 / (255 - src_color);
- if (result > 255) {
- return 255;
- }
- return result;
- }
- case FXDIB_BLEND_COLORBURN: {
- if (src_color == 0) {
- return src_color;
- }
- int result = (255 - back_color) * 255 / src_color;
- if (result > 255) {
- result = 255;
- }
- return 255 - result;
- }
- case FXDIB_BLEND_HARDLIGHT:
- if (src_color < 128) {
- return (src_color * back_color * 2) / 255;
- }
- return _BLEND(FXDIB_BLEND_SCREEN, back_color, 2 * src_color - 255);
- case FXDIB_BLEND_SOFTLIGHT: {
- if (src_color < 128) {
- return back_color - (255 - 2 * src_color) * back_color * (255 - back_color) / 255 / 255;
- }
- return back_color + (2 * src_color - 255) * (_color_sqrt[back_color] - back_color) / 255;
- }
- case FXDIB_BLEND_DIFFERENCE:
- return back_color < src_color ? src_color - back_color : back_color - src_color;
- case FXDIB_BLEND_EXCLUSION:
- return back_color + src_color - 2 * back_color * src_color / 255;
- }
- return src_color;
-}
-struct _RGB {
- int red;
- int green;
- int blue;
-};
-static inline int _Lum(_RGB color)
-{
- return (color.red * 30 + color.green * 59 + color.blue * 11) / 100;
-}
-static _RGB _ClipColor(_RGB color)
-{
- int l = _Lum(color);
- int n = color.red;
- if (color.green < n) {
- n = color.green;
- }
- if (color.blue < n) {
- n = color.blue;
- }
- int x = color.red;
- if (color.green > x) {
- x = color.green;
- }
- if (color.blue > x) {
- x = color.blue;
- }
- if (n < 0) {
- color.red = l + ((color.red - l) * l / (l - n));
- color.green = l + ((color.green - l) * l / (l - n));
- color.blue = l + ((color.blue - l) * l / (l - n));
- }
- if (x > 255) {
- color.red = l + ((color.red - l) * (255 - l) / (x - l));
- color.green = l + ((color.green - l) * (255 - l) / (x - l));
- color.blue = l + ((color.blue - l) * (255 - l) / (x - l));
- }
- return color;
-}
-static _RGB _SetLum(_RGB color, int l)
-{
- int d = l - _Lum(color);
- color.red += d;
- color.green += d;
- color.blue += d;
- return _ClipColor(color);
-}
-static int _Sat(_RGB color)
-{
- int n = color.red;
- if (color.green < n) {
- n = color.green;
- }
- if (color.blue < n) {
- n = color.blue;
- }
- int x = color.red;
- if (color.green > x) {
- x = color.green;
- }
- if (color.blue > x) {
- x = color.blue;
- }
- return x - n;
-}
-static _RGB _SetSat(_RGB color, int s)
-{
- int* max = &color.red;
- int* mid = &color.red;
- int* min = &color.red;
- if (color.green > *max) {
- max = &color.green;
- }
- if (color.blue > *max) {
- max = &color.blue;
- }
- if (color.green < *min) {
- min = &color.green;
- }
- if (color.blue < *min) {
- min = &color.blue;
- }
- if (*max == *min) {
- color.red = 0;
- color.green = 0;
- color.blue = 0;
- return color;
- }
- if (max == &color.red) {
- if (min == &color.green) {
- mid = &color.blue;
- } else {
- mid = &color.green;
- }
- } else if (max == &color.green) {
- if (min == &color.red) {
- mid = &color.blue;
- } else {
- mid = &color.red;
- }
- } else {
- if (min == &color.green) {
- mid = &color.red;
- } else {
- mid = &color.green;
- }
- }
- if (*max > *min) {
- *mid = (*mid - *min) * s / (*max - *min);
- *max = s;
- *min = 0;
- }
- return color;
-}
-void _RGB_Blend(int blend_mode, FX_LPCBYTE src_scan, FX_BYTE* dest_scan, int results[3])
-{
- _RGB src, back, result;
- src.red = src_scan[2];
- src.green = src_scan[1];
- src.blue = src_scan[0];
- back.red = dest_scan[2];
- back.green = dest_scan[1];
- back.blue = dest_scan[0];
- switch (blend_mode) {
- case FXDIB_BLEND_HUE:
- result = _SetLum(_SetSat(src, _Sat(back)), _Lum(back));
- break;
- case FXDIB_BLEND_SATURATION:
- result = _SetLum(_SetSat(back, _Sat(src)), _Lum(back));
- break;
- case FXDIB_BLEND_COLOR:
- result = _SetLum(src, _Lum(back));
- break;
- case FXDIB_BLEND_LUMINOSITY:
- result = _SetLum(back, _Lum(src));
- break;
- }
- results[0] = result.blue;
- results[1] = result.green;
- results[2] = result.red;
-}
-inline void _CompositeRow_Argb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, FX_LPCBYTE clip_scan)
-{
- src_scan += 3;
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha = *src_scan;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- FX_BYTE back_alpha = *dest_scan;
- if (!back_alpha) {
- *dest_scan = src_alpha;
- } else if (src_alpha) {
- *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- }
- dest_scan ++;
- src_scan += 4;
- }
-}
-void _CompositeRow_Rgba2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_alpha_scan, int pixel_count, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- FX_BYTE back_alpha = *dest_scan;
- if (!back_alpha) {
- *dest_scan = src_alpha;
- } else if (src_alpha) {
- *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- }
- dest_scan ++;
- }
-}
-void _CompositeRow_Rgb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan)
-{
- if (clip_scan) {
- for (int i = 0; i < width; i ++) {
- *dest_scan = FXDIB_ALPHA_UNION(*dest_scan, *clip_scan);
- dest_scan ++;
- clip_scan ++;
- }
- } else {
- FXSYS_memset8(dest_scan, 0xff, width);
- }
-}
-void _CompositeRow_Argb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_alpha_scan, FX_LPBYTE dst_alpha_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = NULL;
- if (pIccTransform) {
- pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- }
- if (blend_type) {
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int blended_color;
- if (src_alpha_scan) {
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE back_alpha = *dst_alpha_scan;
- if (back_alpha == 0) {
- int src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
- } else {
- *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dst_alpha_scan = src_alpha;
- }
- dest_scan ++;
- dst_alpha_scan ++;
- src_scan += 3;
- continue;
- }
- FX_BYTE src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dst_alpha_scan ++;
- src_scan += 3;
- continue;
- }
- *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
- int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
- FX_BYTE gray;
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- dst_alpha_scan++;
- src_scan += 3;
- }
- } else
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE back_alpha = *dst_alpha_scan;
- if (back_alpha == 0) {
- int src_alpha = src_scan[3];
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
- } else {
- *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dst_alpha_scan = src_alpha;
- }
- dest_scan ++;
- dst_alpha_scan ++;
- src_scan += 4;
- continue;
- }
- FX_BYTE src_alpha = src_scan[3];
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dst_alpha_scan ++;
- src_scan += 4;
- continue;
- }
- *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
- int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
- FX_BYTE gray;
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- dst_alpha_scan++;
- src_scan += 4;
- }
- return;
- }
- if (src_alpha_scan) {
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE back_alpha = *dst_alpha_scan;
- if (back_alpha == 0) {
- int src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
- } else {
- *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dst_alpha_scan = src_alpha;
- }
- dest_scan ++;
- dst_alpha_scan ++;
- src_scan += 3;
- continue;
- }
- FX_BYTE src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dst_alpha_scan ++;
- src_scan += 3;
- continue;
- }
- *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
- int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
- FX_BYTE gray;
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- dst_alpha_scan++;
- src_scan += 3;
- }
- } else
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE back_alpha = *dst_alpha_scan;
- if (back_alpha == 0) {
- int src_alpha = src_scan[3];
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
- } else {
- *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dst_alpha_scan = src_alpha;
- }
- dest_scan ++;
- dst_alpha_scan ++;
- src_scan += 4;
- continue;
- }
- FX_BYTE src_alpha = src_scan[3];
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dst_alpha_scan ++;
- src_scan += 4;
- continue;
- }
- *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
- int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
- FX_BYTE gray;
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- dst_alpha_scan++;
- src_scan += 4;
- }
-}
-inline void _CompositeRow_Argb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count,
- int blend_type, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_alpha_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = NULL;
- FX_BYTE gray;
- if (pIccTransform) {
- pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- }
- if (blend_type) {
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int blended_color;
- if (src_alpha_scan) {
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
- }
- dest_scan ++;
- src_scan += 3;
- }
- } else
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha = src_scan[3];
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
- }
- dest_scan ++;
- src_scan += 4;
- }
- return;
- }
- if (src_alpha_scan) {
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
- }
- dest_scan ++;
- src_scan += 3;
- }
- } else
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha = src_scan[3];
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
- }
- dest_scan ++;
- src_scan += 4;
- }
-}
-inline void _CompositeRow_Rgb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
- int blend_type, FX_LPCBYTE clip_scan,
- void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = NULL;
- FX_BYTE gray;
- if (pIccTransform) {
- pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- }
- if (blend_type) {
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int blended_color;
- for (int col = 0; col < pixel_count; col ++) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- if (clip_scan && clip_scan[col] < 255) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
- } else {
- *dest_scan = gray;
- }
- dest_scan ++;
- src_scan += src_Bpp;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- if (clip_scan && clip_scan[col] < 255) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
- } else {
- *dest_scan = gray;
- }
- dest_scan ++;
- src_scan += src_Bpp;
- }
-}
-void _CompositeRow_Rgb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
- int blend_type, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = NULL;
- if (pIccTransform) {
- pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- }
- if (blend_type) {
- int blended_color;
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- for (int col = 0; col < pixel_count; col ++) {
- int back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
- } else {
- *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- dest_scan ++;
- dest_alpha_scan++;
- src_scan += src_Bpp;
- continue;
- }
- int src_alpha = 255;
- if (clip_scan) {
- src_alpha = clip_scan[col];
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- src_scan += src_Bpp;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- FX_BYTE gray;
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- src_scan += src_Bpp;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha = 255;
- if (clip_scan) {
- src_alpha = clip_scan[col];
- }
- if (src_alpha == 255) {
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
- } else {
- *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- dest_scan ++;
- *dest_alpha_scan++ = 255;
- src_scan += src_Bpp;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- src_scan += src_Bpp;
- continue;
- }
- int back_alpha = *dest_alpha_scan;
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- FX_BYTE gray;
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
- } else {
- gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
- }
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- src_scan += src_Bpp;
- }
-}
-void _CompositeRow_Argb2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- if (dest_alpha_scan == NULL) {
- if (src_alpha_scan == NULL) {
- FX_BYTE back_alpha = 0;
- for (int col = 0; col < pixel_count; col ++) {
- back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- if (clip_scan) {
- int src_alpha = clip_scan[col] * src_scan[3] / 255;
- FXARGB_SETDIB(dest_scan, (FXARGB_GETDIB(src_scan) & 0xffffff) | (src_alpha << 24));
- } else {
- FXARGB_COPY(dest_scan, src_scan);
- }
- dest_scan += 4;
- src_scan += 4;
- continue;
- }
- FX_BYTE src_alpha;
- if (clip_scan == NULL) {
- src_alpha = src_scan[3];
- } else {
- src_alpha = clip_scan[col] * src_scan[3] / 255;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- src_scan += 4;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- if (blend_type) {
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, *dest_scan, *src_scan);
- blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
- }
- dest_scan ++;
- src_scan ++;
- }
- dest_scan ++;
- src_scan ++;
- }
- } else {
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- if (clip_scan) {
- int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE((src_alpha << 24), src_scan[2], src_scan[1], *src_scan));
- } else {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE((*src_alpha_scan << 24), src_scan[2], src_scan[1], *src_scan));
- }
- dest_scan += 4;
- src_scan += 3;
- src_alpha_scan ++;
- continue;
- }
- FX_BYTE src_alpha;
- if (clip_scan == NULL) {
- src_alpha = *src_alpha_scan ++;
- } else {
- src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- if (blend_type) {
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, *dest_scan, *src_scan);
- blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
- }
- dest_scan ++;
- src_scan ++;
- }
- dest_scan ++;
- }
- }
- } else {
- if (src_alpha_scan) {
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- if (clip_scan) {
- int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
- *dest_alpha_scan = src_alpha;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- } else {
- *dest_alpha_scan = *src_alpha_scan;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- }
- dest_alpha_scan ++;
- src_alpha_scan ++;
- continue;
- }
- FX_BYTE src_alpha;
- if (clip_scan == NULL) {
- src_alpha = *src_alpha_scan ++;
- } else {
- src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
- }
- if (src_alpha == 0) {
- dest_scan += 3;
- src_scan += 3;
- dest_alpha_scan ++;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- if (blend_type) {
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, *dest_scan, *src_scan);
- blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
- }
- dest_scan ++;
- src_scan ++;
- }
- }
- } else {
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- if (clip_scan) {
- int src_alpha = clip_scan[col] * src_scan[3] / 255;
- *dest_alpha_scan = src_alpha;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- } else {
- *dest_alpha_scan = src_scan[3];
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- }
- dest_alpha_scan ++;
- src_scan ++;
- continue;
- }
- FX_BYTE src_alpha;
- if (clip_scan == NULL) {
- src_alpha = src_scan[3];
- } else {
- src_alpha = clip_scan[col] * src_scan[3] / 255;
- }
- if (src_alpha == 0) {
- dest_scan += 3;
- src_scan += 4;
- dest_alpha_scan ++;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- if (blend_type) {
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, *dest_scan, *src_scan);
- blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
- }
- dest_scan ++;
- src_scan ++;
- }
- src_scan ++;
- }
- }
- }
-}
-void _CompositeRow_Rgb2Argb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
- FX_LPBYTE dest_alpha_scan)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int src_gap = src_Bpp - 3;
- if (dest_alpha_scan == NULL) {
- for (int col = 0; col < width; col ++) {
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- if (src_Bpp == 4) {
- FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
- } else {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
- }
- dest_scan += 4;
- src_scan += src_Bpp;
- continue;
- }
- dest_scan[3] = 0xff;
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int src_color = *src_scan;
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, *dest_scan, src_color);
- *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
- dest_scan ++;
- src_scan ++;
- }
- dest_scan ++;
- src_scan += src_gap;
- }
- } else {
- for (int col = 0; col < width; col ++) {
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_alpha_scan++ = 0xff;
- src_scan += src_gap;
- continue;
- }
- *dest_alpha_scan++ = 0xff;
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int src_color = *src_scan;
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, *dest_scan, src_color);
- *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
- dest_scan ++;
- src_scan ++;
- }
- src_scan += src_gap;
- }
- }
-}
-inline void _CompositeRow_Rgb2Argb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int src_gap = src_Bpp - 3;
- if (dest_alpha_scan == NULL) {
- for (int col = 0; col < width; col ++) {
- int src_alpha = *clip_scan ++;
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- src_scan += src_gap;
- dest_scan ++;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- src_scan += src_Bpp;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int src_color = *src_scan;
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, *dest_scan, src_color);
- blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- src_scan ++;
- }
- dest_scan ++;
- src_scan += src_gap;
- }
- } else {
- for (int col = 0; col < width; col ++) {
- int src_alpha = *clip_scan ++;
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- src_scan += src_gap;
- dest_alpha_scan++;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += 3;
- dest_alpha_scan++;
- src_scan += src_Bpp;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int src_color = *src_scan;
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, *dest_scan, src_color);
- blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- src_scan ++;
- }
- src_scan += src_gap;
- }
- }
-}
-inline void _CompositeRow_Rgb2Argb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan)
-{
- int src_gap = src_Bpp - 3;
- if (dest_alpha_scan == NULL) {
- for (int col = 0; col < width; col ++) {
- int src_alpha = clip_scan[col];
- if (src_alpha == 255) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = 255;
- src_scan += src_gap;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- src_scan += src_Bpp;
- continue;
- }
- int back_alpha = dest_scan[3];
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- for (int color = 0; color < 3; color ++) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
- dest_scan ++;
- src_scan ++;
- }
- dest_scan ++;
- src_scan += src_gap;
- }
- } else {
- for (int col = 0; col < width; col ++) {
- int src_alpha = clip_scan[col];
- if (src_alpha == 255) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_alpha_scan++ = 255;
- src_scan += src_gap;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += 3;
- dest_alpha_scan ++;
- src_scan += src_Bpp;
- continue;
- }
- int back_alpha = *dest_alpha_scan;
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- for (int color = 0; color < 3; color ++) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
- dest_scan ++;
- src_scan ++;
- }
- src_scan += src_gap;
- }
- }
-}
-inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
- FX_LPBYTE dest_alpha_scan)
-{
- if (dest_alpha_scan == NULL) {
- for (int col = 0; col < width; col ++) {
- if (src_Bpp == 4) {
- FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
- } else {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
- }
- dest_scan += 4;
- src_scan += src_Bpp;
- }
- } else {
- int src_gap = src_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_alpha_scan++ = 0xff;
- src_scan += src_gap;
- }
- }
-}
-inline void _CompositeRow_Argb2Rgb_Blend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_alpha_scan)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int dest_gap = dest_Bpp - 3;
- if (src_alpha_scan == NULL) {
- for (int col = 0; col < width; col ++) {
- FX_BYTE src_alpha;
- if (clip_scan) {
- src_alpha = src_scan[3] * (*clip_scan++) / 255;
- } else {
- src_alpha = src_scan[3];
- }
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_scan += 4;
- continue;
- }
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int back_color = *dest_scan;
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, back_color, *src_scan);
- *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
- dest_scan ++;
- src_scan ++;
- }
- dest_scan += dest_gap;
- src_scan ++;
- }
- } else {
- for (int col = 0; col < width; col ++) {
- FX_BYTE src_alpha;
- if (clip_scan) {
- src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
- } else {
- src_alpha = *src_alpha_scan++;
- }
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_scan += 3;
- continue;
- }
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int back_color = *dest_scan;
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, back_color, *src_scan);
- *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
- dest_scan ++;
- src_scan ++;
- }
- dest_scan += dest_gap;
- }
- }
-}
-inline void _CompositeRow_Argb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_alpha_scan)
-{
- int dest_gap = dest_Bpp - 3;
- if (src_alpha_scan == NULL) {
- for (int col = 0; col < width; col ++) {
- FX_BYTE src_alpha;
- if (clip_scan) {
- src_alpha = src_scan[3] * (*clip_scan++) / 255;
- } else {
- src_alpha = src_scan[3];
- }
- if (src_alpha == 255) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- dest_scan += dest_gap;
- src_scan ++;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_scan += 4;
- continue;
- }
- for (int color = 0; color < 3; color ++) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
- dest_scan ++;
- src_scan ++;
- }
- dest_scan += dest_gap;
- src_scan ++;
- }
- } else {
- for (int col = 0; col < width; col ++) {
- FX_BYTE src_alpha;
- if (clip_scan) {
- src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
- } else {
- src_alpha = *src_alpha_scan++;
- }
- if (src_alpha == 255) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- dest_scan += dest_gap;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_scan += 3;
- continue;
- }
- for (int color = 0; color < 3; color ++) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
- dest_scan ++;
- src_scan ++;
- }
- dest_scan += dest_gap;
- }
- }
-}
-inline void _CompositeRow_Rgb2Rgb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int dest_gap = dest_Bpp - 3;
- int src_gap = src_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int back_color = *dest_scan;
- int src_color = *src_scan;
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, back_color, src_color);
- *dest_scan = blended;
- dest_scan ++;
- src_scan ++;
- }
- dest_scan += dest_gap;
- src_scan += src_gap;
- }
-}
-inline void _CompositeRow_Rgb2Rgb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int dest_gap = dest_Bpp - 3;
- int src_gap = src_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- FX_BYTE src_alpha = *clip_scan ++;
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_scan += src_Bpp;
- continue;
- }
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int src_color = *src_scan;
- int back_color = *dest_scan;
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, back_color, src_color);
- *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
- dest_scan ++;
- src_scan ++;
- }
- dest_scan += dest_gap;
- src_scan += src_gap;
- }
-}
-inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
-{
- if (dest_Bpp == src_Bpp) {
- FXSYS_memcpy32(dest_scan, src_scan, width * dest_Bpp);
- return;
- }
- for (int col = 0; col < width; col ++) {
- dest_scan[0] = src_scan[0];
- dest_scan[1] = src_scan[1];
- dest_scan[2] = src_scan[2];
- dest_scan += dest_Bpp;
- src_scan += src_Bpp;
- }
-}
-inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < width; col ++) {
- int src_alpha = clip_scan[col];
- if (src_alpha == 255) {
- dest_scan[0] = src_scan[0];
- dest_scan[1] = src_scan[1];
- dest_scan[2] = src_scan[2];
- } else if (src_alpha) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
- dest_scan ++;
- src_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
- dest_scan ++;
- src_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
- dest_scan += dest_Bpp - 2;
- src_scan += src_Bpp - 2;
- continue;
- }
- dest_scan += dest_Bpp;
- src_scan += src_Bpp;
- }
-}
-void _CompositeRow_Argb2Argb_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- FX_LPBYTE dp = src_cache_scan;
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_alpha_scan) {
- if (dest_alpha_scan == NULL) {
- for (int col = 0; col < pixel_count; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- dp[3] = *src_alpha_scan++;
- src_scan += 3;
- dp += 4;
- }
- src_alpha_scan = NULL;
- } else {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, pixel_count);
- }
- } else {
- if (dest_alpha_scan == NULL) {
- for (int col = 0; col < pixel_count; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- dp[3] = src_scan[3];
- src_scan += 4;
- dp += 4;
- }
- } else {
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- for (int col = 0; col < pixel_count; col ++) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- if (clip_scan) {
- int src_alpha = clip_scan[col] * src_scan[3] / 255;
- *dest_alpha_scan = src_alpha;
- *dest_scan++ = *src_cache_scan++;
- *dest_scan++ = *src_cache_scan++;
- *dest_scan++ = *src_cache_scan++;
- } else {
- *dest_alpha_scan = src_scan[3];
- *dest_scan++ = *src_cache_scan++;
- *dest_scan++ = *src_cache_scan++;
- *dest_scan++ = *src_cache_scan++;
- }
- dest_alpha_scan ++;
- src_scan += 4;
- continue;
- }
- FX_BYTE src_alpha;
- if (clip_scan == NULL) {
- src_alpha = src_scan[3];
- } else {
- src_alpha = clip_scan[col] * src_scan[3] / 255;
- }
- src_scan += 4;
- if (src_alpha == 0) {
- dest_scan += 3;
- src_cache_scan += 3;
- dest_alpha_scan ++;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- if (blend_type) {
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, *dest_scan, *src_cache_scan);
- blended = FXDIB_ALPHA_MERGE(*src_cache_scan, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, alpha_ratio);
- }
- dest_scan ++;
- src_cache_scan ++;
- }
- }
- return;
- }
- }
- _CompositeRow_Argb2Argb(dest_scan, src_cache_scan, pixel_count, blend_type, clip_scan, dest_alpha_scan, src_alpha_scan);
-}
-void _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
- FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_Bpp == 3) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- FX_LPBYTE dp = src_cache_scan;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- src_scan += 4;
- dp += 3;
- }
- }
- _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, 3, dest_alpha_scan);
-}
-inline void _CompositeRow_Rgb2Argb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_Bpp == 3) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- FX_LPBYTE dp = src_cache_scan;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- src_scan += 4;
- dp += 3;
- }
- }
- _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, 3, clip_scan, dest_alpha_scan);
-}
-inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_Bpp == 3) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- FX_LPBYTE dp = src_cache_scan;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- src_scan += 4;
- dp += 3;
- }
- }
- _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_cache_scan, width, 3, clip_scan, dest_alpha_scan);
-}
-inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
- FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_Bpp == 3) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- FX_LPBYTE dp = src_cache_scan;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- src_scan += 4;
- dp += 3;
- }
- }
- _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_cache_scan, width, 3, dest_alpha_scan);
-}
-inline void _CompositeRow_Argb2Rgb_Blend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_alpha_scan) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int dest_gap = dest_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
- FX_BYTE src_alpha;
- if (clip_scan) {
- src_alpha = src_scan[3] * (*clip_scan++) / 255;
- } else {
- src_alpha = src_scan[3];
- }
- src_scan += 4;
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_cache_scan += 3;
- continue;
- }
- if (bNonseparableBlend) {
- _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int back_color = *dest_scan;
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, back_color, *src_cache_scan);
- *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
- dest_scan ++;
- src_cache_scan ++;
- }
- dest_scan += dest_gap;
- }
- return;
- }
- _CompositeRow_Argb2Rgb_Blend(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, clip_scan, src_alpha_scan);
-}
-inline void _CompositeRow_Argb2Rgb_NoBlend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_alpha_scan) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- int dest_gap = dest_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
- FX_BYTE src_alpha;
- if (clip_scan) {
- src_alpha = src_scan[3] * (*clip_scan++) / 255;
- } else {
- src_alpha = src_scan[3];
- }
- src_scan += 4;
- if (src_alpha == 255) {
- *dest_scan++ = *src_cache_scan++;
- *dest_scan++ = *src_cache_scan++;
- *dest_scan++ = *src_cache_scan++;
- dest_scan += dest_gap;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_cache_scan += 3;
- continue;
- }
- for (int color = 0; color < 3; color ++) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, src_alpha);
- dest_scan ++;
- src_cache_scan ++;
- }
- dest_scan += dest_gap;
- }
- return;
- }
- _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_cache_scan, width, dest_Bpp, clip_scan, src_alpha_scan);
-}
-inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp,
- FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_Bpp == 3) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- FX_LPBYTE dp = src_cache_scan;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- src_scan += 4;
- dp += 3;
- }
- }
- _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3);
-}
-inline void _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
- FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_Bpp == 3) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- FX_LPBYTE dp = src_cache_scan;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- src_scan += 4;
- dp += 3;
- }
- }
- _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3, clip_scan);
-}
-inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp,
- FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_Bpp == 3) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- FX_LPBYTE dp = src_cache_scan;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- src_scan += 4;
- dp += 3;
- }
- }
- _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_cache_scan, width, dest_Bpp, 3);
-}
-inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
- FX_LPBYTE src_cache_scan, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (src_Bpp == 3) {
- pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
- } else {
- FX_LPBYTE dp = src_cache_scan;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
- src_scan += 4;
- dp += 3;
- }
- }
- _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_cache_scan, width, dest_Bpp, 3, clip_scan);
-}
-inline void _CompositeRow_8bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
- int blend_type, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_alpha_scan)
-{
- if (src_alpha_scan) {
- if (blend_type) {
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int blended_color;
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = pPalette[*src_scan];
- int src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- if (src_alpha) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
- } else {
- *dest_scan = gray;
- }
- dest_scan ++;
- src_scan ++;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = pPalette[*src_scan];
- int src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
- } else {
- *dest_scan = gray;
- }
- dest_scan ++;
- src_scan ++;
- }
- } else {
- if (blend_type) {
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int blended_color;
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = pPalette[*src_scan];
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- if (clip_scan && clip_scan[col] < 255) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
- } else {
- *dest_scan = gray;
- }
- dest_scan ++;
- src_scan ++;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = pPalette[*src_scan];
- if (clip_scan && clip_scan[col] < 255) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
- } else {
- *dest_scan = gray;
- }
- dest_scan ++;
- src_scan ++;
- }
- }
-}
-inline void _CompositeRow_8bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
- int blend_type, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
-{
- if (src_alpha_scan) {
- if (blend_type) {
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int blended_color;
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = pPalette[*src_scan];
- src_scan ++;
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- int src_alpha = *src_alpha_scan ++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- *dest_scan = gray;
- *dest_alpha_scan = src_alpha;
- }
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- FX_BYTE src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_alpha_scan ++;
- dest_scan ++;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = pPalette[*src_scan];
- src_scan ++;
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- int src_alpha = *src_alpha_scan ++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha) {
- *dest_scan = gray;
- *dest_alpha_scan = src_alpha;
- }
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- FX_BYTE src_alpha = *src_alpha_scan++;
- if (clip_scan) {
- src_alpha = clip_scan[col] * src_alpha / 255;
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
- dest_alpha_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- }
- } else {
- if (blend_type) {
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int blended_color;
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = pPalette[*src_scan];
- src_scan ++;
- if (clip_scan == NULL || clip_scan[col] == 255) {
- *dest_scan++ = gray;
- *dest_alpha_scan++ = 255;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- int back_alpha = *dest_alpha_scan;
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = pPalette[*src_scan];
- src_scan ++;
- if (clip_scan == NULL || clip_scan[col] == 255) {
- *dest_scan++ = gray;
- *dest_alpha_scan++ = 255;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- int back_alpha = *dest_alpha_scan;
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- }
- }
-}
-inline void _CompositeRow_1bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
- FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
-{
- int reset_gray = pPalette[0];
- int set_gray = pPalette[1];
- if (blend_type) {
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int blended_color;
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- if (clip_scan && clip_scan[col] < 255) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
- } else {
- *dest_scan = gray;
- }
- dest_scan ++;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
- if (clip_scan && clip_scan[col] < 255) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
- } else {
- *dest_scan = gray;
- }
- dest_scan ++;
- }
-}
-inline void _CompositeRow_1bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
- FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan)
-{
- int reset_gray = pPalette[0];
- int set_gray = pPalette[1];
- if (blend_type) {
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int blended_color;
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
- if (clip_scan == NULL || clip_scan[col] == 255) {
- *dest_scan++ = gray;
- *dest_alpha_scan ++ = 255;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- int back_alpha = *dest_alpha_scan;
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
- }
- gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
- if (clip_scan == NULL || clip_scan[col] == 255) {
- *dest_scan++ = gray;
- *dest_alpha_scan ++ = 255;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- int back_alpha = *dest_alpha_scan;
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
- dest_scan ++;
- }
-}
-inline void _CompositeRow_8bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_DWORD* pPalette, int pixel_count,
- int DestBpp, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_alpha_scan)
-{
- if (src_alpha_scan) {
- int dest_gap = DestBpp - 3;
- FX_ARGB argb = 0;
- for (int col = 0; col < pixel_count; col ++) {
- argb = pPalette[*src_scan];
- int src_r = FXARGB_R(argb);
- int src_g = FXARGB_G(argb);
- int src_b = FXARGB_B(argb);
- src_scan ++;
- FX_BYTE src_alpha = 0;
- if (clip_scan) {
- src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
- } else {
- src_alpha = *src_alpha_scan++;
- }
- if (src_alpha == 255) {
- *dest_scan++ = src_b;
- *dest_scan++ = src_g;
- *dest_scan++ = src_r;
- dest_scan += dest_gap;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += DestBpp;
- continue;
- }
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
- dest_scan ++;
- dest_scan += dest_gap;
- }
- } else {
- FX_ARGB argb = 0;
- for (int col = 0; col < pixel_count; col ++) {
- argb = pPalette[*src_scan];
- int src_r = FXARGB_R(argb);
- int src_g = FXARGB_G(argb);
- int src_b = FXARGB_B(argb);
- if (clip_scan && clip_scan[col] < 255) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
- dest_scan ++;
- } else {
- *dest_scan++ = src_b;
- *dest_scan++ = src_g;
- *dest_scan++ = src_r;
- }
- if (DestBpp == 4) {
- dest_scan++;
- }
- src_scan ++;
- }
- }
-}
-inline void _CompositeRow_1bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
- FX_DWORD* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
-{
- int reset_r, reset_g, reset_b;
- int set_r, set_g, set_b;
- reset_r = FXARGB_R(pPalette[0]);
- reset_g = FXARGB_G(pPalette[0]);
- reset_b = FXARGB_B(pPalette[0]);
- set_r = FXARGB_R(pPalette[1]);
- set_g = FXARGB_G(pPalette[1]);
- set_b = FXARGB_B(pPalette[1]);
- for (int col = 0; col < pixel_count; col ++) {
- int src_r, src_g, src_b;
- if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
- src_r = set_r;
- src_g = set_g;
- src_b = set_b;
- } else {
- src_r = reset_r;
- src_g = reset_g;
- src_b = reset_b;
- }
- if (clip_scan && clip_scan[col] < 255) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
- dest_scan ++;
- } else {
- *dest_scan++ = src_b;
- *dest_scan++ = src_g;
- *dest_scan++ = src_r;
- }
- if (DestBpp == 4) {
- dest_scan++;
- }
- }
-}
-inline void _CompositeRow_8bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
- FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_alpha_scan)
-{
- if (src_alpha_scan) {
- for (int col = 0; col < width; col ++) {
- FX_ARGB argb = pPalette[*src_scan];
- src_scan ++;
- int src_r = FXARGB_R(argb);
- int src_g = FXARGB_G(argb);
- int src_b = FXARGB_B(argb);
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- if (clip_scan) {
- int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
- } else {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(*src_alpha_scan, src_r, src_g, src_b));
- }
- dest_scan += 4;
- src_alpha_scan ++;
- continue;
- }
- FX_BYTE src_alpha;
- if (clip_scan == NULL) {
- src_alpha = *src_alpha_scan ++;
- } else {
- src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- dest_scan ++;
- dest_scan ++;
- }
- } else
- for (int col = 0; col < width; col ++) {
- FX_ARGB argb = pPalette[*src_scan];
- int src_r = FXARGB_R(argb);
- int src_g = FXARGB_G(argb);
- int src_b = FXARGB_B(argb);
- if (clip_scan == NULL || clip_scan[col] == 255) {
- *dest_scan++ = src_b;
- *dest_scan++ = src_g;
- *dest_scan++ = src_r;
- *dest_scan++ = 255;
- src_scan ++;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan += 4;
- src_scan ++;
- continue;
- }
- int back_alpha = dest_scan[3];
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- dest_scan ++;
- dest_scan ++;
- src_scan ++;
- }
-}
-void _CompositeRow_8bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
- FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
-{
- if (src_alpha_scan) {
- for (int col = 0; col < width; col ++) {
- FX_ARGB argb = pPalette[*src_scan];
- src_scan ++;
- int src_r = FXARGB_R(argb);
- int src_g = FXARGB_G(argb);
- int src_b = FXARGB_B(argb);
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- if (clip_scan) {
- int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
- *dest_alpha_scan ++ = src_alpha;
- } else {
- *dest_alpha_scan ++ = *src_alpha_scan;
- }
- *dest_scan ++ = src_b;
- *dest_scan ++ = src_g;
- *dest_scan ++ = src_r;
- src_alpha_scan ++;
- continue;
- }
- FX_BYTE src_alpha;
- if (clip_scan == NULL) {
- src_alpha = *src_alpha_scan++;
- } else {
- src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
- }
- if (src_alpha == 0) {
- dest_scan += 3;
- dest_alpha_scan ++;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- dest_scan ++;
- }
- } else
- for (int col = 0; col < width; col ++) {
- FX_ARGB argb = pPalette[*src_scan];
- int src_r = FXARGB_R(argb);
- int src_g = FXARGB_G(argb);
- int src_b = FXARGB_B(argb);
- if (clip_scan == NULL || clip_scan[col] == 255) {
- *dest_scan++ = src_b;
- *dest_scan++ = src_g;
- *dest_scan++ = src_r;
- *dest_alpha_scan++ = 255;
- src_scan ++;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan += 3;
- dest_alpha_scan ++;
- src_scan ++;
- continue;
- }
- int back_alpha = *dest_alpha_scan;
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- dest_scan ++;
- src_scan ++;
- }
-}
-inline void _CompositeRow_1bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
- FX_DWORD* pPalette, FX_LPCBYTE clip_scan)
-{
- int reset_r, reset_g, reset_b;
- int set_r, set_g, set_b;
- reset_r = FXARGB_R(pPalette[0]);
- reset_g = FXARGB_G(pPalette[0]);
- reset_b = FXARGB_B(pPalette[0]);
- set_r = FXARGB_R(pPalette[1]);
- set_g = FXARGB_G(pPalette[1]);
- set_b = FXARGB_B(pPalette[1]);
- for (int col = 0; col < width; col ++) {
- int src_r, src_g, src_b;
- if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
- src_r = set_r;
- src_g = set_g;
- src_b = set_b;
- } else {
- src_r = reset_r;
- src_g = reset_g;
- src_b = reset_b;
- }
- if (clip_scan == NULL || clip_scan[col] == 255) {
- *dest_scan++ = src_b;
- *dest_scan++ = src_g;
- *dest_scan++ = src_r;
- *dest_scan++ = 255;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan += 4;
- continue;
- }
- int back_alpha = dest_scan[3];
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- dest_scan ++;
- dest_scan ++;
- }
-}
-void _CompositeRow_1bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
- FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan)
-{
- int reset_r, reset_g, reset_b;
- int set_r, set_g, set_b;
- reset_r = FXARGB_R(pPalette[0]);
- reset_g = FXARGB_G(pPalette[0]);
- reset_b = FXARGB_B(pPalette[0]);
- set_r = FXARGB_R(pPalette[1]);
- set_g = FXARGB_G(pPalette[1]);
- set_b = FXARGB_B(pPalette[1]);
- for (int col = 0; col < width; col ++) {
- int src_r, src_g, src_b;
- if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
- src_r = set_r;
- src_g = set_g;
- src_b = set_b;
- } else {
- src_r = reset_r;
- src_g = reset_g;
- src_b = reset_b;
- }
- if (clip_scan == NULL || clip_scan[col] == 255) {
- *dest_scan++ = src_b;
- *dest_scan++ = src_g;
- *dest_scan++ = src_r;
- *dest_alpha_scan++ = 255;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan += 3;
- dest_alpha_scan ++;
- continue;
- }
- int back_alpha = *dest_alpha_scan;
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- dest_scan ++;
- }
-}
-void _CompositeRow_ByteMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
- int blend_type, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
- } else {
- src_alpha = mask_alpha * src_scan[col] / 255;
- }
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
- dest_scan += 4;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
- } else if (blend_type) {
- int blended = _BLEND(blend_type, *dest_scan, src_b);
- blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_g);
- blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_r);
- blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- }
- dest_scan += 2;
- }
-}
-void _CompositeRow_ByteMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
- int blend_type, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
- } else {
- src_alpha = mask_alpha * src_scan[col] / 255;
- }
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- *dest_scan ++ = src_b;
- *dest_scan ++ = src_g;
- *dest_scan ++ = src_r;
- *dest_alpha_scan ++ = src_alpha;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += 3;
- dest_alpha_scan ++;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
- dest_scan ++;
- } else if (blend_type) {
- int blended = _BLEND(blend_type, *dest_scan, src_b);
- blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_g);
- blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_r);
- blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- dest_scan ++;
- }
- }
-}
-void _CompositeRow_ByteMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
- int blend_type, int Bpp, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
- } else {
- src_alpha = mask_alpha * src_scan[col] / 255;
- }
- if (src_alpha == 0) {
- dest_scan += Bpp;
- continue;
- }
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
- } else if (blend_type) {
- int blended = _BLEND(blend_type, *dest_scan, src_b);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_g);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_r);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
- }
- dest_scan += Bpp - 2;
- }
-}
-void _CompositeRow_ByteMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int pixel_count,
- FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
- } else {
- src_alpha = mask_alpha * src_scan[col] / 255;
- }
- FX_BYTE back_alpha = *dest_scan;
- if (!back_alpha) {
- *dest_scan = src_alpha;
- } else if (src_alpha) {
- *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- }
- dest_scan ++;
- }
-}
-void _CompositeRow_ByteMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
- int pixel_count, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
- } else {
- src_alpha = mask_alpha * src_scan[col] / 255;
- }
- if (src_alpha) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
- }
- dest_scan ++;
- }
-}
-void _CompositeRow_ByteMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
- int pixel_count, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
- } else {
- src_alpha = mask_alpha * src_scan[col] / 255;
- }
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- *dest_scan ++ = src_gray;
- *dest_alpha_scan ++ = src_alpha;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
- dest_scan ++;
- }
-}
-void _CompositeRow_BitMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
- int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
-{
- if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
- FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
- for (int col = 0; col < pixel_count; col ++) {
- if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
- FXARGB_SETDIB(dest_scan, argb);
- }
- dest_scan += 4;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
- dest_scan += 4;
- continue;
- }
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] / 255;
- } else {
- src_alpha = mask_alpha;
- }
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
- dest_scan += 4;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
- } else if (blend_type) {
- int blended = _BLEND(blend_type, *dest_scan, src_b);
- blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_g);
- blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_r);
- blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- }
- dest_scan += 2;
- }
-}
-void _CompositeRow_BitMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
- int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan)
-{
- if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
- for (int col = 0; col < pixel_count; col ++) {
- if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
- dest_scan[0] = src_b;
- dest_scan[1] = src_g;
- dest_scan[2] = src_r;
- *dest_alpha_scan = mask_alpha;
- }
- dest_scan += 3;
- dest_alpha_scan ++;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
- dest_scan += 3;
- dest_alpha_scan ++;
- continue;
- }
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] / 255;
- } else {
- src_alpha = mask_alpha;
- }
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- *dest_scan ++ = src_b;
- *dest_scan ++ = src_g;
- *dest_scan ++ = src_r;
- *dest_alpha_scan ++ = mask_alpha;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
- dest_scan ++;
- } else if (blend_type) {
- int blended = _BLEND(blend_type, *dest_scan, src_b);
- blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_g);
- blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- blended = _BLEND(blend_type, *dest_scan, src_r);
- blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
- dest_scan ++;
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
- dest_scan ++;
- }
- }
-}
-void _CompositeRow_BitMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
- int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
-{
- if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
- for (int col = 0; col < pixel_count; col ++) {
- if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
- dest_scan[2] = src_r;
- dest_scan[1] = src_g;
- dest_scan[0] = src_b;
- }
- dest_scan += Bpp;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
- dest_scan += Bpp;
- continue;
- }
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] / 255;
- } else {
- src_alpha = mask_alpha;
- }
- if (src_alpha == 0) {
- dest_scan += Bpp;
- continue;
- }
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
- } else if (blend_type) {
- int blended = _BLEND(blend_type, *dest_scan, src_b);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
- dest_scan++;
- blended = _BLEND(blend_type, *dest_scan, src_g);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
- dest_scan++;
- blended = _BLEND(blend_type, *dest_scan, src_r);
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
- } else {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
- }
- dest_scan += Bpp - 2;
- }
-}
-void _CompositeRow_BitMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_left,
- int pixel_count, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
- dest_scan ++;
- continue;
- }
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] / 255;
- } else {
- src_alpha = mask_alpha;
- }
- FX_BYTE back_alpha = *dest_scan;
- if (!back_alpha) {
- *dest_scan = src_alpha;
- } else if (src_alpha) {
- *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- }
- dest_scan ++;
- }
-}
-void _CompositeRow_BitMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
- int src_left, int pixel_count, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
- dest_scan ++;
- continue;
- }
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] / 255;
- } else {
- src_alpha = mask_alpha;
- }
- if (src_alpha) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
- }
- dest_scan ++;
- }
-}
-void _CompositeRow_BitMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
- int src_left, int pixel_count, FX_LPCBYTE clip_scan,
- FX_LPBYTE dest_alpha_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] / 255;
- } else {
- src_alpha = mask_alpha;
- }
- FX_BYTE back_alpha = *dest_alpha_scan;
- if (back_alpha == 0) {
- *dest_scan ++ = src_gray;
- *dest_alpha_scan ++ = src_alpha;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan ++;
- dest_alpha_scan ++;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_alpha_scan++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
- dest_scan ++;
- }
-}
-void _CompositeRow_Argb2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- for (int col = 0; col < pixel_count; col ++) {
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- if (clip_scan) {
- int src_alpha = clip_scan[col] * src_scan[3] / 255;
- dest_scan[3] = src_alpha;
- dest_scan[0] = src_scan[2];
- dest_scan[1] = src_scan[1];
- dest_scan[2] = src_scan[0];
- } else {
- FXARGB_RGBORDERCOPY(dest_scan, src_scan);
- }
- dest_scan += 4;
- src_scan += 4;
- continue;
- }
- FX_BYTE src_alpha;
- if (clip_scan == NULL) {
- src_alpha = src_scan[3];
- } else {
- src_alpha = clip_scan[col] * src_scan[3] / 255;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- src_scan += 4;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- FX_BYTE dest_scan_o[3];
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int index = 2 - color;
- if (blend_type) {
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, dest_scan[index], *src_scan);
- blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
- dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
- } else {
- dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], *src_scan, alpha_ratio);
- }
- src_scan ++;
- }
- dest_scan += 4;
- src_scan++;
- }
-}
-void _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int src_gap = src_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- if (src_Bpp == 4) {
- FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
- } else {
- FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
- }
- dest_scan += 4;
- src_scan += src_Bpp;
- continue;
- }
- dest_scan[3] = 0xff;
- if (bNonseparableBlend) {
- FX_BYTE dest_scan_o[3];
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int index = 2 - color;
- int src_color = FX_GAMMA(*src_scan);
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, dest_scan[index], src_color);
- dest_scan[index] = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
- src_scan ++;
- }
- dest_scan += 4;
- src_scan += src_gap;
- }
-}
-inline void _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- for (int col = 0; col < width; col ++) {
- FX_BYTE src_alpha;
- if (clip_scan) {
- src_alpha = src_scan[3] * (*clip_scan++) / 255;
- } else {
- src_alpha = src_scan[3];
- }
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_scan += 4;
- continue;
- }
- if (bNonseparableBlend) {
- FX_BYTE dest_scan_o[3];
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int index = 2 - color;
- int back_color = FX_GAMMA(dest_scan[index]);
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, back_color, *src_scan);
- dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
- src_scan ++;
- }
- dest_scan += dest_Bpp;
- src_scan ++;
- }
-}
-inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp)
-{
- int src_gap = src_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- if (src_Bpp == 4) {
- FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
- } else {
- FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
- }
- dest_scan += 4;
- src_scan += src_Bpp;
- }
-}
-inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int src_gap = src_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- if (bNonseparableBlend) {
- FX_BYTE dest_scan_o[3];
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int index = 2 - color;
- int back_color = FX_GAMMA(dest_scan[index]);
- int src_color = FX_GAMMA(*src_scan);
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, back_color, src_color);
- dest_scan[index] = FX_GAMMA_INVERSE(blended);
- src_scan ++;
- }
- dest_scan += dest_Bpp;
- src_scan += src_gap;
- }
-}
-inline void _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < width; col ++) {
- FX_BYTE src_alpha;
- if (clip_scan) {
- src_alpha = src_scan[3] * (*clip_scan++) / 255;
- } else {
- src_alpha = src_scan[3];
- }
- if (src_alpha == 255) {
- dest_scan[2] = FX_GAMMA_INVERSE(*src_scan++);
- dest_scan[1] = FX_GAMMA_INVERSE(*src_scan++);
- dest_scan[0] = FX_GAMMA_INVERSE(*src_scan++);
- dest_scan += dest_Bpp;
- src_scan ++;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_scan += 4;
- continue;
- }
- for (int color = 0; color < 3; color ++) {
- int index = 2 - color;
- dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[index]), *src_scan, src_alpha));
- src_scan ++;
- }
- dest_scan += dest_Bpp;
- src_scan ++;
- }
-}
-inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
-{
- for (int col = 0; col < width; col ++) {
- dest_scan[2] = src_scan[0];
- dest_scan[1] = src_scan[1];
- dest_scan[0] = src_scan[2];
- dest_scan += dest_Bpp;
- src_scan += src_Bpp;
- }
-}
-inline void _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int src_gap = src_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- int src_alpha = *clip_scan ++;
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- dest_scan[2] = FX_GAMMA(*src_scan++);
- dest_scan[1] = FX_GAMMA(*src_scan++);
- dest_scan[0] = FX_GAMMA(*src_scan++);
- src_scan += src_gap;
- dest_scan += 4;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- src_scan += src_Bpp;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (bNonseparableBlend) {
- FX_BYTE dest_scan_o[3];
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int index = 2 - color;
- int src_color = FX_GAMMA(*src_scan);
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, dest_scan[index], src_color);
- blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
- dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
- src_scan ++;
- }
- dest_scan += 4;
- src_scan += src_gap;
- }
-}
-inline void _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
-{
- int blended_colors[3];
- FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
- int src_gap = src_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- FX_BYTE src_alpha = *clip_scan ++;
- if (src_alpha == 0) {
- dest_scan += dest_Bpp;
- src_scan += src_Bpp;
- continue;
- }
- if (bNonseparableBlend) {
- FX_BYTE dest_scan_o[3];
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- }
- for (int color = 0; color < 3; color ++) {
- int index = 2 - color;
- int src_color = FX_GAMMA(*src_scan);
- int back_color = FX_GAMMA(dest_scan[index]);
- int blended = bNonseparableBlend ? blended_colors[color] :
- _BLEND(blend_type, back_color, src_color);
- dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
- src_scan ++;
- }
- dest_scan += dest_Bpp;
- src_scan += src_gap;
- }
-}
-inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan)
-{
- int src_gap = src_Bpp - 3;
- for (int col = 0; col < width; col ++) {
- int src_alpha = clip_scan[col];
- if (src_alpha == 255) {
- dest_scan[2] = FX_GAMMA(*src_scan++);
- dest_scan[1] = FX_GAMMA(*src_scan++);
- dest_scan[0] = FX_GAMMA(*src_scan++);
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += src_gap;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- src_scan += src_Bpp;
- continue;
- }
- int back_alpha = dest_scan[3];
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- for (int color = 0; color < 3; color ++) {
- int index = 2 - color;
- dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], FX_GAMMA(*src_scan), alpha_ratio);
- src_scan ++;
- }
- dest_scan += 4;
- src_scan += src_gap;
- }
-}
-inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < width; col ++) {
- int src_alpha = clip_scan[col];
- if (src_alpha == 255) {
- dest_scan[2] = src_scan[0];
- dest_scan[1] = src_scan[1];
- dest_scan[0] = src_scan[2];
- } else if (src_alpha) {
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), FX_GAMMA(*src_scan), src_alpha));
- src_scan ++;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), FX_GAMMA(*src_scan), src_alpha));
- src_scan ++;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), FX_GAMMA(*src_scan), src_alpha));
- dest_scan += dest_Bpp;
- src_scan += src_Bpp - 2;
- continue;
- }
- dest_scan += dest_Bpp;
- src_scan += src_Bpp;
- }
-}
-inline void _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_ARGB* pPalette, int pixel_count,
- int DestBpp, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- FX_ARGB argb = pPalette ? pPalette[*src_scan] : (*src_scan) * 0x010101;
- int src_r = FXARGB_R(argb);
- int src_g = FXARGB_G(argb);
- int src_b = FXARGB_B(argb);
- if (clip_scan && clip_scan[col] < 255) {
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
- } else {
- dest_scan[2] = src_b;
- dest_scan[1] = src_g;
- dest_scan[0] = src_r;
- }
- dest_scan += DestBpp;
- src_scan ++;
- }
-}
-inline void _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
- FX_ARGB* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
-{
- int reset_r, reset_g, reset_b;
- int set_r, set_g, set_b;
- if (pPalette) {
- reset_r = FXARGB_R(pPalette[0]);
- reset_g = FXARGB_G(pPalette[0]);
- reset_b = FXARGB_B(pPalette[0]);
- set_r = FXARGB_R(pPalette[1]);
- set_g = FXARGB_G(pPalette[1]);
- set_b = FXARGB_B(pPalette[1]);
- } else {
- reset_r = reset_g = reset_b = 0;
- set_r = set_g = set_b = 255;
- }
- for (int col = 0; col < pixel_count; col ++) {
- int src_r, src_g, src_b;
- if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
- src_r = set_r;
- src_g = set_g;
- src_b = set_b;
- } else {
- src_r = reset_r;
- src_g = reset_g;
- src_b = reset_b;
- }
- if (clip_scan && clip_scan[col] < 255) {
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
- } else {
- dest_scan[2] = src_b;
- dest_scan[1] = src_g;
- dest_scan[0] = src_r;
- }
- dest_scan += DestBpp;
- }
-}
-inline void _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
- FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < width; col ++) {
- int src_r, src_g, src_b;
- if (pPalette) {
- FX_ARGB argb = pPalette[*src_scan];
- src_r = FXARGB_R(argb);
- src_g = FXARGB_G(argb);
- src_b = FXARGB_B(argb);
- } else {
- src_r = src_g = src_b = *src_scan;
- }
- if (clip_scan == NULL || clip_scan[col] == 255) {
- dest_scan[2] = FX_GAMMA(src_b);
- dest_scan[1] = FX_GAMMA(src_g);
- dest_scan[0] = FX_GAMMA(src_r);
- dest_scan[3] = 255;
- src_scan ++;
- dest_scan += 4;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan += 4;
- src_scan ++;
- continue;
- }
- int back_alpha = dest_scan[3];
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
- dest_scan += 4;
- src_scan ++;
- }
-}
-inline void _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
- FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
-{
- int reset_r, reset_g, reset_b;
- int set_r, set_g, set_b;
- if (pPalette) {
- reset_r = FXARGB_R(pPalette[0]);
- reset_g = FXARGB_G(pPalette[0]);
- reset_b = FXARGB_B(pPalette[0]);
- set_r = FXARGB_R(pPalette[1]);
- set_g = FXARGB_G(pPalette[1]);
- set_b = FXARGB_B(pPalette[1]);
- } else {
- reset_r = reset_g = reset_b = 0;
- set_r = set_g = set_b = 255;
- }
- for (int col = 0; col < width; col ++) {
- int src_r, src_g, src_b;
- if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
- src_r = set_r;
- src_g = set_g;
- src_b = set_b;
- } else {
- src_r = reset_r;
- src_g = reset_g;
- src_b = reset_b;
- }
- if (clip_scan == NULL || clip_scan[col] == 255) {
- dest_scan[2] = FX_GAMMA(src_b);
- dest_scan[1] = FX_GAMMA(src_g);
- dest_scan[0] = FX_GAMMA(src_r);
- dest_scan[3] = 255;
- dest_scan += 4;
- continue;
- }
- int src_alpha = clip_scan[col];
- if (src_alpha == 0) {
- dest_scan += 4;
- continue;
- }
- int back_alpha = dest_scan[3];
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
- dest_scan += 4;
- }
-}
-void _CompositeRow_ByteMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
- int blend_type, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
- } else {
- src_alpha = mask_alpha * src_scan[col] / 255;
- }
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
- dest_scan += 4;
- continue;
- }
- if (src_alpha == 0) {
- dest_scan += 4;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- FX_BYTE dest_scan_o[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
- } else if (blend_type) {
- int blended = _BLEND(blend_type, dest_scan[2], src_b);
- blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
- blended = _BLEND(blend_type, dest_scan[1], src_g);
- blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
- blended = _BLEND(blend_type, dest_scan[0], src_r);
- blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
- } else {
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
- }
- dest_scan += 4;
- }
-}
-void _CompositeRow_ByteMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
- int blend_type, int Bpp, FX_LPCBYTE clip_scan)
-{
- for (int col = 0; col < pixel_count; col ++) {
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
- } else {
- src_alpha = mask_alpha * src_scan[col] / 255;
- }
- if (src_alpha == 0) {
- dest_scan += Bpp;
- continue;
- }
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- FX_BYTE dest_scan_o[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
- } else if (blend_type) {
- int blended = _BLEND(blend_type, dest_scan[2], src_b);
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha);
- blended = _BLEND(blend_type, dest_scan[1], src_g);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, src_alpha);
- blended = _BLEND(blend_type, dest_scan[0], src_r);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, src_alpha);
- } else {
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, src_alpha);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, src_alpha);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, src_alpha);
- }
- dest_scan += Bpp;
- }
-}
-void _CompositeRow_BitMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
- int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
-{
- if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
- FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
- for (int col = 0; col < pixel_count; col ++) {
- if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
- FXARGB_SETRGBORDERDIB(dest_scan, argb);
- }
- dest_scan += 4;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
- dest_scan += 4;
- continue;
- }
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] / 255;
- } else {
- src_alpha = mask_alpha;
- }
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
- dest_scan += 4;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- FX_BYTE dest_scan_o[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
- } else if (blend_type) {
- int blended = _BLEND(blend_type, dest_scan[2], src_b);
- blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
- blended = _BLEND(blend_type, dest_scan[1], src_g);
- blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
- blended = _BLEND(blend_type, dest_scan[0], src_r);
- blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
- } else {
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
- }
- dest_scan += 4;
- }
-}
-void _CompositeRow_BitMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
- int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
-{
- if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
- for (int col = 0; col < pixel_count; col ++) {
- if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
- dest_scan[2] = src_b;
- dest_scan[1] = src_g;
- dest_scan[0] = src_r;
- }
- dest_scan += Bpp;
- }
- return;
- }
- for (int col = 0; col < pixel_count; col ++) {
- if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
- dest_scan += Bpp;
- continue;
- }
- int src_alpha;
- if (clip_scan) {
- src_alpha = mask_alpha * clip_scan[col] / 255;
- } else {
- src_alpha = mask_alpha;
- }
- if (src_alpha == 0) {
- dest_scan += Bpp;
- continue;
- }
- if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
- int blended_colors[3];
- FX_BYTE src_scan[3];
- FX_BYTE dest_scan_o[3];
- src_scan[0] = src_b;
- src_scan[1] = src_g;
- src_scan[2] = src_r;
- dest_scan_o[0] = dest_scan[2];
- dest_scan_o[1] = dest_scan[1];
- dest_scan_o[2] = dest_scan[0];
- _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
- dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
- dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
- dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
- } else if (blend_type) {
- int back_color = FX_GAMMA(dest_scan[2]);
- int blended = _BLEND(blend_type, back_color, src_b);
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
- back_color = FX_GAMMA(dest_scan[1]);
- blended = _BLEND(blend_type, back_color, src_g);
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
- back_color = FX_GAMMA(dest_scan[0]);
- blended = _BLEND(blend_type, back_color, src_r);
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
- } else {
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), src_b, src_alpha));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), src_g, src_alpha));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), src_r, src_alpha));
- }
- dest_scan += Bpp;
- }
-}
-inline FX_BOOL _ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format, int alpha_flag, FX_DWORD mask_color, int& mask_alpha,
- int& mask_red, int& mask_green, int& mask_blue, int& mask_black,
- void* icc_module, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
- if (alpha_flag >> 8) {
- mask_alpha = alpha_flag & 0xff;
- mask_red = FXSYS_GetCValue(mask_color);
- mask_green = FXSYS_GetMValue(mask_color);
- mask_blue = FXSYS_GetYValue(mask_color);
- mask_black = FXSYS_GetKValue(mask_color);
- } else {
- mask_alpha = FXARGB_A(mask_color);
- mask_red = FXARGB_R(mask_color);
- mask_green = FXARGB_G(mask_color);
- mask_blue = FXARGB_B(mask_color);
- }
- if (dest_format == FXDIB_8bppMask) {
- return TRUE;
- }
- if ((dest_format & 0xff) == 8) {
- if (pIccTransform) {
- mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
- FX_LPBYTE gray_p = (FX_LPBYTE)&mask_color;
- pIccModule->TranslateScanline(pIccTransform, gray_p, gray_p, 1);
- mask_red = dest_format & 0x0400 ? FX_CCOLOR(gray_p[0]) : gray_p[0];
- } else {
- if (alpha_flag >> 8) {
- FX_BYTE r, g, b;
- AdobeCMYK_to_sRGB1(mask_red, mask_green, mask_blue, mask_black,
- r, g, b);
- mask_red = FXRGB2GRAY(r, g, b);
- } else {
- mask_red = FXRGB2GRAY(mask_red, mask_green, mask_blue);
- }
- if (dest_format & 0x0400) {
- mask_red = FX_CCOLOR(mask_red);
- }
- }
- } else {
- FX_LPBYTE mask_color_p = (FX_LPBYTE)&mask_color;
- mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
- if (pIccTransform) {
- pIccModule->TranslateScanline(pIccTransform, mask_color_p, mask_color_p, 1);
- mask_red = mask_color_p[2];
- mask_green = mask_color_p[1];
- mask_blue = mask_color_p[0];
- } else if (alpha_flag >> 8) {
- AdobeCMYK_to_sRGB1(mask_color_p[0], mask_color_p[1], mask_color_p[2], mask_color_p[3],
- mask_color_p[2], mask_color_p[1], mask_color_p[0]);
- mask_red = mask_color_p[2];
- mask_green = mask_color_p[1];
- mask_blue = mask_color_p[0];
- }
- }
- return TRUE;
-}
-inline void _ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format, FXDIB_Format dest_format,
- FX_DWORD*& pDestPalette, FX_DWORD* pSrcPalette,
- void* icc_module, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
- FX_BOOL isSrcCmyk = src_format & 0x0400 ? TRUE : FALSE;
- FX_BOOL isDstCmyk = dest_format & 0x0400 ? TRUE : FALSE;
- pDestPalette = NULL;
- if (pIccTransform) {
- if (pSrcPalette) {
- if ((dest_format & 0xff) == 8) {
- int pal_count = 1 << (src_format & 0xff);
- FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
- if (!gray_pal) {
- return;
- }
- pDestPalette = (FX_DWORD*)gray_pal;
- for (int i = 0; i < pal_count; i ++) {
- FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
- pIccModule->TranslateScanline(pIccTransform, gray_pal, (FX_LPCBYTE)&color, 1);
- gray_pal ++;
- }
- } else {
- int palsize = 1 << (src_format & 0xff);
- pDestPalette = FX_Alloc(FX_DWORD, palsize);
- if (!pDestPalette) {
- return;
- }
- for (int i = 0; i < palsize; i ++) {
- FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
- pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&color, (FX_LPCBYTE)&color, 1);
- pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
- }
- }
- } else {
- int pal_count = 1 << (src_format & 0xff);
- FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
- if (!gray_pal) {
- return;
- }
- if (pal_count == 2) {
- gray_pal[0] = 0;
- gray_pal[1] = 255;
- } else {
- for (int i = 0; i < pal_count; i++) {
- gray_pal[i] = i;
- }
- }
- if ((dest_format & 0xff) == 8) {
- pIccModule->TranslateScanline(pIccTransform, gray_pal, gray_pal, pal_count);
- pDestPalette = (FX_DWORD*)gray_pal;
- } else {
- pDestPalette = FX_Alloc(FX_DWORD, pal_count);
- if (!pDestPalette) {
- FX_Free(gray_pal);
- return;
- }
- for (int i = 0; i < pal_count; i ++) {
- pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&pDestPalette[i], &gray_pal[i], 1);
- pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(pDestPalette[i]) : FXARGB_TODIB(pDestPalette[i]);
- }
- FX_Free(gray_pal);
- }
- }
- } else {
- if (pSrcPalette) {
- if ((dest_format & 0xff) == 8) {
- int pal_count = 1 << (src_format & 0xff);
- FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
- if (!gray_pal) {
- return;
- }
- pDestPalette = (FX_DWORD*)gray_pal;
- if (isSrcCmyk) {
- for (int i = 0; i < pal_count; i ++) {
- FX_CMYK cmyk = pSrcPalette[i];
- FX_BYTE r, g, b;
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
- r, g, b);
- *gray_pal ++ = FXRGB2GRAY(r, g, b);
- }
- } else
- for (int i = 0; i < pal_count; i ++) {
- FX_ARGB argb = pSrcPalette[i];
- *gray_pal ++ = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
- }
- } else {
- int palsize = 1 << (src_format & 0xff);
- pDestPalette = FX_Alloc(FX_DWORD, palsize);
- if (!pDestPalette) {
- return;
- }
- if (isDstCmyk == isSrcCmyk) {
- FXSYS_memcpy32(pDestPalette, pSrcPalette, palsize * sizeof(FX_DWORD));
- } else {
- for (int i = 0; i < palsize; i ++) {
- FX_CMYK cmyk = pSrcPalette[i];
- FX_BYTE r, g, b;
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
- r, g, b);
- pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
- }
- }
- }
- } else {
- if ((dest_format & 0xff) == 8) {
- int pal_count = 1 << (src_format & 0xff);
- FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
- if (!gray_pal) {
- return;
- }
- if (pal_count == 2) {
- gray_pal[0] = 0;
- gray_pal[1] = 255;
- } else {
- for (int i = 0; i < pal_count; i++) {
- gray_pal[i] = i;
- }
- }
- pDestPalette = (FX_DWORD*)gray_pal;
- } else {
- int palsize = 1 << (src_format & 0xff);
- pDestPalette = FX_Alloc(FX_DWORD, palsize);
- if (!pDestPalette) {
- return;
- }
- if (palsize == 2) {
- pDestPalette[0] = isSrcCmyk ? 255 : 0xff000000;
- pDestPalette[1] = isSrcCmyk ? 0 : 0xffffffff;
- } else {
- for (int i = 0; i < palsize; i++) {
- pDestPalette[i] = isSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101);
- }
- }
- if (isSrcCmyk != isDstCmyk) {
- for (int i = 0; i < palsize; i ++) {
- FX_CMYK cmyk = pDestPalette[i];
- FX_BYTE r, g, b;
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
- r, g, b);
- pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
- }
- }
- }
- }
- }
-}
-CFX_ScanlineCompositor::CFX_ScanlineCompositor()
-{
- m_pSrcPalette = NULL;
- m_pCacheScanline = NULL;
- m_CacheSize = 0;
- m_bRgbByteOrder = FALSE;
- m_BlendType = FXDIB_BLEND_NORMAL;
-}
-CFX_ScanlineCompositor::~CFX_ScanlineCompositor()
-{
- if (m_pSrcPalette) {
- FX_Free(m_pSrcPalette);
- }
- if (m_pCacheScanline) {
- FX_Free(m_pCacheScanline);
- }
-}
-FX_BOOL CFX_ScanlineCompositor::Init(FXDIB_Format dest_format, FXDIB_Format src_format, FX_INT32 width, FX_DWORD* pSrcPalette,
- FX_DWORD mask_color, int blend_type, FX_BOOL bClip, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
-{
- m_SrcFormat = src_format;
- m_DestFormat = dest_format;
- m_BlendType = blend_type;
- m_bRgbByteOrder = bRgbByteOrder;
- ICodec_IccModule* pIccModule = NULL;
- if (CFX_GEModule::Get()->GetCodecModule()) {
- pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- }
- if (pIccModule == NULL) {
- pIccTransform = NULL;
- }
- m_pIccTransform = pIccTransform;
- if ((dest_format & 0xff) == 1) {
- return FALSE;
- }
- if (m_SrcFormat == FXDIB_1bppMask || m_SrcFormat == FXDIB_8bppMask) {
- return _ScanlineCompositor_InitSourceMask(dest_format, alpha_flag, mask_color,
- m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, m_MaskBlack,
- pIccModule, pIccTransform);
- }
- if (pIccTransform == NULL && (~src_format & 0x0400) && (dest_format & 0x0400)) {
- return FALSE;
- }
- if ((m_SrcFormat & 0xff) <= 8) {
- if (dest_format == FXDIB_8bppMask) {
- return TRUE;
- }
- _ScanlineCompositor_InitSourcePalette(src_format, dest_format, m_pSrcPalette, pSrcPalette,
- pIccModule, pIccTransform);
- m_Transparency = (dest_format == FXDIB_Argb ? 1 : 0)
- + (dest_format & 0x0200 ? 2 : 0)
- + (dest_format & 0x0400 ? 4 : 0)
- + ((src_format & 0xff) == 1 ? 8 : 0);
- return TRUE;
- }
- m_Transparency = (src_format & 0x0200 ? 0 : 1)
- + (dest_format & 0x0200 ? 0 : 2)
- + (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0)
- + (bClip ? 8 : 0)
- + (src_format & 0x0400 ? 16 : 0)
- + (dest_format & 0x0400 ? 32 : 0)
- + (pIccTransform ? 64 : 0);
- return TRUE;
-}
-void CFX_ScanlineCompositor::CompositeRgbBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
-{
- int src_Bpp = (m_SrcFormat & 0xff) >> 3;
- int dest_Bpp = (m_DestFormat & 0xff) >> 3;
- int dest_Size = width * dest_Bpp + 4;
- if (m_bRgbByteOrder) {
- switch (m_Transparency) {
- case 0:
- case 4:
- case 8:
- case 12:
- _CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, clip_scan);
- break;
- case 1:
- _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp);
- break;
- case 2:
- case 10:
- _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan);
- break;
- case 3:
- _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
- break;
- case 5:
- _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp);
- break;
- case 6:
- case 14:
- _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, clip_scan);
- break;
- case 7:
- _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
- break;
- case 9:
- _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan);
- break;
- case 11:
- _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
- break;
- case 13:
- _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp, clip_scan);
- break;
- case 15:
- _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
- break;
- }
- return;
- }
- if (m_DestFormat == FXDIB_8bppMask) {
- if (m_SrcFormat & 0x0200) {
- if (m_SrcFormat == FXDIB_Argb) {
- _CompositeRow_Argb2Mask(dest_scan, src_scan, width, clip_scan);
- } else {
- _CompositeRow_Rgba2Mask(dest_scan, src_extra_alpha, width, clip_scan);
- }
- } else {
- _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
- }
- } else if ((m_DestFormat & 0xff) == 8) {
- if (m_DestFormat & 0x0400) {
- for (int i = 0; i < width; i ++) {
- *dest_scan = ~*dest_scan;
- dest_scan++;
- }
- }
- if (m_SrcFormat & 0x0200) {
- if (m_DestFormat & 0x0200) {
- _CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, dst_extra_alpha, m_pIccTransform);
- } else {
- _CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, m_pIccTransform);
- }
- } else {
- if (m_DestFormat & 0x0200) {
- _CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, dst_extra_alpha, m_pIccTransform);
- } else {
- _CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, m_pIccTransform);
- }
- }
- if (m_DestFormat & 0x0400) {
- for (int i = 0; i < width; i ++) {
- *dest_scan = ~*dest_scan;
- dest_scan++;
- }
- }
- } else {
- if (dest_Size > m_CacheSize) {
- m_pCacheScanline = FX_Realloc(FX_BYTE, m_pCacheScanline, dest_Size);
- if (!m_pCacheScanline) {
- return;
- }
- m_CacheSize = dest_Size;
- }
- switch (m_Transparency) {
- case 0:
- case 4:
- case 8:
- case 4+8: {
- _CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType, clip_scan,
- dst_extra_alpha, src_extra_alpha);
- }
- break;
- case 64:
- case 4+64:
- case 8+64:
- case 4+8+64: {
- _CompositeRow_Argb2Argb_Transform(dest_scan, src_scan, width, m_BlendType, clip_scan,
- dst_extra_alpha, src_extra_alpha, m_pCacheScanline, m_pIccTransform);
- }
- break;
- case 1:
- _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, src_Bpp,
- dst_extra_alpha);
- break;
- case 1+64:
- _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp,
- dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
- break;
- case 1+8:
- _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
- dst_extra_alpha);
- break;
- case 1+8+64:
- _CompositeRow_Rgb2Argb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
- dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
- break;
- case 1+4:
- _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width, src_Bpp,
- dst_extra_alpha);
- break;
- case 1+4+64:
- _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, src_Bpp,
- dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
- break;
- case 1+4+8:
- _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp, clip_scan,
- dst_extra_alpha);
- break;
- case 1+4+8+64:
- _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(dest_scan, src_scan, width, src_Bpp, clip_scan,
- dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
- break;
- case 2:
- case 2+8:
- _CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
- src_extra_alpha);
- break;
- case 2+64:
- case 2+8+64:
- _CompositeRow_Argb2Rgb_Blend_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
- src_extra_alpha, m_pCacheScanline, m_pIccTransform);
- break;
- case 2+4:
- case 2+4+8:
- _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp, clip_scan,
- src_extra_alpha);
- break;
- case 2+4+64:
- case 2+4+8+64:
- _CompositeRow_Argb2Rgb_NoBlend_Transform(dest_scan, src_scan, width, dest_Bpp, clip_scan,
- src_extra_alpha, m_pCacheScanline, m_pIccTransform);
- break;
- case 1+2:
- _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
- break;
- case 1+2+64:
- _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp,
- m_pCacheScanline, m_pIccTransform);
- break;
- case 1+2+8:
- _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
- break;
- case 1+2+8+64:
- _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan,
- m_pCacheScanline, m_pIccTransform);
- break;
- case 1+2+4:
- _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
- break;
- case 1+2+4+64:
- _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp,
- m_pCacheScanline, m_pIccTransform);
- break;
- case 1+2+4+8:
- _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
- break;
- case 1+2+4+8+64:
- _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan,
- m_pCacheScanline, m_pIccTransform);
- break;
- }
- }
-}
-void CFX_ScanlineCompositor::CompositePalBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
-{
- if (m_bRgbByteOrder) {
- if (m_SrcFormat == FXDIB_1bppRgb) {
- if (m_DestFormat == FXDIB_8bppRgb) {
- return;
- } else if(m_DestFormat == FXDIB_Argb) {
- _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
- } else {
- _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
- }
- } else {
- if (m_DestFormat == FXDIB_8bppRgb) {
- return;
- } else if (m_DestFormat == FXDIB_Argb) {
- _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, m_pSrcPalette, clip_scan);
- } else {
- _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
- }
- }
- return;
- }
- if (m_DestFormat == FXDIB_8bppMask) {
- _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
- return;
- } else if ((m_DestFormat & 0xff) == 8) {
- if (m_Transparency & 8) {
- if (m_DestFormat & 0x0200) {
- _CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan, dst_extra_alpha);
- } else {
- _CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan);
- }
- } else {
- if (m_DestFormat & 0x0200)
- _CompositeRow_8bppPal2Graya(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
- dst_extra_alpha, src_extra_alpha);
- else
- _CompositeRow_8bppPal2Gray(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
- src_extra_alpha);
- }
- } else {
- switch (m_Transparency) {
- case 1+2:
- _CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width, m_pSrcPalette, clip_scan,
- src_extra_alpha);
- break;
- case 1+2+8:
- _CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
- break;
- case 0:
- _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
- src_extra_alpha);
- break;
- case 0+8:
- _CompositeRow_1bppRgb2Rgb_NoBlend(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
- break;
- case 0+2:
- _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
- src_extra_alpha);
- break;
- case 0+2+8:
- _CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan,
- dst_extra_alpha);
- break;
- break;
- }
- }
-}
-void CFX_ScanlineCompositor::CompositeByteMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
- FX_LPBYTE dst_extra_alpha)
-{
- if (m_DestFormat == FXDIB_8bppMask) {
- _CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width, clip_scan);
- } else if ((m_DestFormat & 0xff) == 8) {
- if (m_DestFormat & 0x0200) {
- _CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan, dst_extra_alpha);
- } else {
- _CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan);
- }
- } else if (m_bRgbByteOrder) {
- if (m_DestFormat == FXDIB_Argb)
- _CompositeRow_ByteMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
- width, m_BlendType, clip_scan);
- else
- _CompositeRow_ByteMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
- width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
- return;
- } else if (m_DestFormat == FXDIB_Argb)
- _CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
- width, m_BlendType, clip_scan);
- else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
- _CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
- width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
- else if (m_DestFormat == FXDIB_Rgba)
- _CompositeRow_ByteMask2Rgba(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
- width, m_BlendType, clip_scan, dst_extra_alpha);
-}
-void CFX_ScanlineCompositor::CompositeBitMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
- FX_LPBYTE dst_extra_alpha)
-{
- if (m_DestFormat == FXDIB_8bppMask) {
- _CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, width, clip_scan);
- } else if ((m_DestFormat & 0xff) == 8) {
- if (m_DestFormat & 0x0200)
- _CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan,
- dst_extra_alpha);
- else {
- _CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan);
- }
- } else if (m_bRgbByteOrder) {
- if (m_DestFormat == FXDIB_Argb)
- _CompositeRow_BitMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
- src_left, width, m_BlendType, clip_scan);
- else
- _CompositeRow_BitMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
- src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
- return;
- } else if (m_DestFormat == FXDIB_Argb)
- _CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
- src_left, width, m_BlendType, clip_scan);
- else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
- _CompositeRow_BitMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
- src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
-}
-FX_BOOL CFX_DIBitmap::CompositeBitmap(int dest_left, int dest_top, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top,
- int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, void* pIccTransform)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- ASSERT(!pSrcBitmap->IsAlphaMask());
- ASSERT(m_bpp >= 8);
- if (pSrcBitmap->IsAlphaMask() || m_bpp < 8) {
- return FALSE;
- }
- GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(),
- src_left, src_top, pClipRgn);
- if (width == 0 || height == 0) {
- return TRUE;
- }
- const CFX_DIBitmap* pClipMask = NULL;
- FX_RECT clip_box;
- if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
- ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
- pClipMask = pClipRgn->GetMask();
- clip_box = pClipRgn->GetBox();
- }
- CFX_ScanlineCompositor compositor;
- if (!compositor.Init(GetFormat(), pSrcBitmap->GetFormat(), width, pSrcBitmap->GetPalette(), 0, blend_type,
- pClipMask != NULL, bRgbByteOrder, 0, pIccTransform)) {
- return FALSE;
- }
- int dest_Bpp = m_bpp / 8;
- int src_Bpp = pSrcBitmap->GetBPP() / 8;
- FX_BOOL bRgb = FALSE;
- FX_BOOL bCmyk = FALSE;
- if (src_Bpp > 1) {
- if (pSrcBitmap->IsCmykImage()) {
- bCmyk = TRUE;
- } else {
- bRgb = TRUE;
- }
- }
- CFX_DIBitmap* pSrcAlphaMask = pSrcBitmap->m_pAlphaMask;
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * dest_Bpp;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * src_Bpp;
- FX_LPCBYTE src_scan_extra_alpha = pSrcAlphaMask ? pSrcAlphaMask->GetScanline(src_top + row) + src_left : NULL;
- FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
- FX_LPCBYTE clip_scan = NULL;
- if (pClipMask) {
- clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
- }
- if (bRgb) {
- compositor.CompositeRgbBitmapLine(dest_scan, src_scan, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
- } else {
- compositor.CompositePalBitmapLine(dest_scan, src_scan, src_left, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
- }
- }
- return TRUE;
-}
-FX_BOOL CFX_DIBitmap::CompositeMask(int dest_left, int dest_top, int width, int height,
- const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top,
- int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- ASSERT(pMask->IsAlphaMask());
- ASSERT(m_bpp >= 8);
- if (!pMask->IsAlphaMask() || m_bpp < 8) {
- return FALSE;
- }
- GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, pClipRgn);
- if (width == 0 || height == 0) {
- return TRUE;
- }
- int src_alpha = (FX_BYTE)(alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
- if (src_alpha == 0) {
- return TRUE;
- }
- const CFX_DIBitmap* pClipMask = NULL;
- FX_RECT clip_box;
- if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
- ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
- pClipMask = pClipRgn->GetMask();
- clip_box = pClipRgn->GetBox();
- }
- int src_bpp = pMask->GetBPP();
- int Bpp = GetBPP() / 8;
- CFX_ScanlineCompositor compositor;
- if (!compositor.Init(GetFormat(), pMask->GetFormat(), width, NULL, color, blend_type, pClipMask != NULL, bRgbByteOrder, alpha_flag, pIccTransform)) {
- return FALSE;
- }
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp;
- FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row);
- FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
- FX_LPCBYTE clip_scan = NULL;
- if (pClipMask) {
- clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
- }
- if (src_bpp == 1) {
- compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width, clip_scan, dst_scan_extra_alpha);
- } else {
- compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width, clip_scan, dst_scan_extra_alpha);
- }
- }
- return TRUE;
-}
-FX_BOOL CFX_DIBitmap::CompositeRect(int left, int top, int width, int height, FX_DWORD color, int alpha_flag, void* pIccTransform)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- int src_alpha = (alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
- if (src_alpha == 0) {
- return TRUE;
- }
- FX_RECT rect(left, top, left + width, top + height);
- rect.Intersect(0, 0, m_Width, m_Height);
- if (rect.IsEmpty()) {
- return TRUE;
- }
- width = rect.Width();
- FX_DWORD dst_color;
- if (alpha_flag >> 8) {
- dst_color = FXCMYK_TODIB(color);
- } else {
- dst_color = FXARGB_TODIB(color);
- }
- FX_LPBYTE color_p = (FX_LPBYTE)&dst_color;
- if (m_bpp == 8) {
- FX_BYTE gray = 255;
- if (!IsAlphaMask()) {
- if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- pIccModule->TranslateScanline(pIccTransform, &gray, color_p, 1);
- } else {
- if (alpha_flag >> 8) {
- FX_BYTE r, g, b;
- AdobeCMYK_to_sRGB1(color_p[0], color_p[1], color_p[2], color_p[3],
- r, g, b);
- gray = FXRGB2GRAY(r, g, b);
- } else {
- gray = (FX_BYTE)FXRGB2GRAY((int)color_p[2], color_p[1], color_p[0]);
- }
- }
- if (IsCmykImage()) {
- gray = ~gray;
- }
- }
- for (int row = rect.top; row < rect.bottom; row ++) {
- FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left;
- if (src_alpha == 255) {
- FXSYS_memset8(dest_scan, gray, width);
- } else
- for (int col = 0; col < width; col ++) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
- dest_scan ++;
- }
- }
- return TRUE;
- } else if (m_bpp == 1) {
- ASSERT(!IsCmykImage() && (FX_BYTE)(alpha_flag >> 8) == 0);
- int left_shift = rect.left % 8;
- int right_shift = rect.right % 8;
- int width = rect.right / 8 - rect.left / 8;
- int index = 0;
- if (m_pPalette == NULL) {
- index = ((FX_BYTE)color == 0xff) ? 1 : 0;
- } else {
- for (int i = 0; i < 2; i ++)
- if (m_pPalette[i] == color) {
- index = i;
- }
- }
- for (int row = rect.top; row < rect.bottom; row ++) {
- FX_BYTE* dest_scan_top = (FX_BYTE*)GetScanline(row) + rect.left / 8;
- FX_BYTE* dest_scan_top_r = (FX_BYTE*)GetScanline(row) + rect.right / 8;
- FX_BYTE left_flag = *dest_scan_top & (255 << (8 - left_shift));
- FX_BYTE right_flag = *dest_scan_top_r & (255 >> right_shift);
- if (width) {
- FXSYS_memset8(dest_scan_top + 1, index ? 255 : 0, width - 1);
- if (!index) {
- *dest_scan_top &= left_flag;
- *dest_scan_top_r &= right_flag;
- } else {
- *dest_scan_top |= ~left_flag;
- *dest_scan_top_r |= ~right_flag;
- }
- } else {
- if (!index) {
- *dest_scan_top &= left_flag | right_flag;
- } else {
- *dest_scan_top |= ~(left_flag | right_flag);
- }
- }
- }
- return TRUE;
- }
- ASSERT(m_bpp >= 24);
- if (m_bpp < 24) {
- return FALSE;
- }
- if (pIccTransform && CFX_GEModule::Get()->GetCodecModule()) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1);
- } else {
- if (alpha_flag >> 8 && !IsCmykImage())
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color),
- color_p[2], color_p[1], color_p[0]);
- else if (!(alpha_flag >> 8) && IsCmykImage()) {
- return FALSE;
- }
- }
- if(!IsCmykImage()) {
- color_p[3] = (FX_BYTE)src_alpha;
- }
- int Bpp = m_bpp / 8;
- FX_BOOL bAlpha = HasAlpha();
- FX_BOOL bArgb = GetFormat() == FXDIB_Argb ? TRUE : FALSE;
- if (src_alpha == 255) {
- for (int row = rect.top; row < rect.bottom; row ++) {
- FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
- FX_LPBYTE dest_scan_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left : NULL;
- if (dest_scan_alpha) {
- FXSYS_memset8(dest_scan_alpha, 0xff, width);
- }
- if (Bpp == 4) {
- FX_DWORD* scan = (FX_DWORD*)dest_scan;
- for (int col = 0; col < width; col ++) {
- *scan ++ = dst_color;
- }
- } else {
- for (int col = 0; col < width; col ++) {
- *dest_scan ++ = color_p[0];
- *dest_scan ++ = color_p[1];
- *dest_scan ++ = color_p[2];
- }
- }
- }
- return TRUE;
- }
- for (int row = rect.top; row < rect.bottom; row ++) {
- FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
- if (bAlpha) {
- if (bArgb) {
- for (int col = 0; col < width; col ++) {
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, color_p[2], color_p[1], color_p[0]));
- dest_scan += 4;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[0], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[1], alpha_ratio);
- dest_scan ++;
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[2], alpha_ratio);
- dest_scan ++;
- *dest_scan++ = dest_alpha;
- }
- } else {
- FX_LPBYTE dest_scan_alpha = (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left;
- for (int col = 0; col < width; col ++) {
- FX_BYTE back_alpha = *dest_scan_alpha;
- if (back_alpha == 0) {
- *dest_scan_alpha++ = src_alpha;
- FXSYS_memcpy32(dest_scan, color_p, Bpp);
- dest_scan += Bpp;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
- *dest_scan_alpha ++ = dest_alpha;
- int alpha_ratio = src_alpha * 255 / dest_alpha;
- for(int comps = 0; comps < Bpp; comps ++) {
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], alpha_ratio);
- dest_scan ++;
- }
- }
- }
- } else {
- for (int col = 0; col < width; col ++) {
- for(int comps = 0; comps < Bpp; comps ++) {
- if (comps == 3) {
- *dest_scan ++ = 255;
- continue;
- }
- *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha);
- dest_scan ++;
- }
- }
- }
- }
- return TRUE;
-}
-CFX_BitmapComposer::CFX_BitmapComposer()
-{
- m_pScanlineV = NULL;
- m_pScanlineAlphaV = NULL;
- m_pClipScanV = NULL;
- m_pAddClipScan = NULL;
- m_bRgbByteOrder = FALSE;
- m_BlendType = FXDIB_BLEND_NORMAL;
-}
-CFX_BitmapComposer::~CFX_BitmapComposer()
-{
- if (m_pScanlineV) {
- FX_Free(m_pScanlineV);
- }
- if (m_pScanlineAlphaV) {
- FX_Free(m_pScanlineAlphaV);
- }
- if (m_pClipScanV) {
- FX_Free(m_pClipScanV);
- }
- if (m_pAddClipScan) {
- FX_Free(m_pAddClipScan);
- }
-}
-void CFX_BitmapComposer::Compose(CFX_DIBitmap* pDest, const CFX_ClipRgn* pClipRgn, int bitmap_alpha,
- FX_DWORD mask_color, FX_RECT& dest_rect, FX_BOOL bVertical,
- FX_BOOL bFlipX, FX_BOOL bFlipY, FX_BOOL bRgbByteOrder,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- m_pBitmap = pDest;
- m_pClipRgn = pClipRgn;
- m_DestLeft = dest_rect.left;
- m_DestTop = dest_rect.top;
- m_DestWidth = dest_rect.Width();
- m_DestHeight = dest_rect.Height();
- m_BitmapAlpha = bitmap_alpha;
- m_MaskColor = mask_color;
- m_pClipMask = NULL;
- if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
- m_pClipMask = pClipRgn->GetMask();
- }
- m_bVertical = bVertical;
- m_bFlipX = bFlipX;
- m_bFlipY = bFlipY;
- m_AlphaFlag = alpha_flag;
- m_pIccTransform = pIccTransform;
- m_bRgbByteOrder = bRgbByteOrder;
- m_BlendType = blend_type;
-}
-FX_BOOL CFX_BitmapComposer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette)
-{
- m_SrcFormat = src_format;
- if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette, m_MaskColor, FXDIB_BLEND_NORMAL,
- m_pClipMask != NULL || (m_BitmapAlpha < 255), m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform)) {
- return FALSE;
- }
- if (m_bVertical) {
- m_pScanlineV = FX_Alloc(FX_BYTE, m_pBitmap->GetBPP() / 8 * width + 4);
- if (!m_pScanlineV) {
- return FALSE;
- }
- m_pClipScanV = FX_Alloc(FX_BYTE, m_pBitmap->GetHeight());
- if (!m_pClipScanV) {
- return FALSE;
- }
- if (m_pBitmap->m_pAlphaMask) {
- m_pScanlineAlphaV = FX_Alloc(FX_BYTE, width + 4);
- if (!m_pScanlineAlphaV) {
- return FALSE;
- }
- }
- }
- if (m_BitmapAlpha < 255) {
- m_pAddClipScan = FX_Alloc(FX_BYTE, m_bVertical ? m_pBitmap->GetHeight() : m_pBitmap->GetWidth());
- if (!m_pAddClipScan) {
- return FALSE;
- }
- }
- return TRUE;
-}
-void CFX_BitmapComposer::DoCompose(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int dest_width, FX_LPCBYTE clip_scan,
- FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
-{
- if (m_BitmapAlpha < 255) {
- if (clip_scan) {
- for (int i = 0; i < dest_width; i ++) {
- m_pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255;
- }
- } else {
- FXSYS_memset8(m_pAddClipScan, m_BitmapAlpha, dest_width);
- }
- clip_scan = m_pAddClipScan;
- }
- if (m_SrcFormat == FXDIB_8bppMask) {
- m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width, clip_scan, dst_extra_alpha);
- } else if ((m_SrcFormat & 0xff) == 8) {
- m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
- } else {
- m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
- }
-}
-void CFX_BitmapComposer::ComposeScanline(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
-{
- if (m_bVertical) {
- ComposeScanlineV(line, scanline, scan_extra_alpha);
- return;
- }
- FX_LPCBYTE clip_scan = NULL;
- if (m_pClipMask)
- clip_scan = m_pClipMask->GetBuffer() + (m_DestTop + line - m_pClipRgn->GetBox().top) *
- m_pClipMask->GetPitch() + (m_DestLeft - m_pClipRgn->GetBox().left);
- FX_LPBYTE dest_scan = (FX_LPBYTE)m_pBitmap->GetScanline(line + m_DestTop) +
- m_DestLeft * m_pBitmap->GetBPP() / 8;
- FX_LPBYTE dest_alpha_scan = m_pBitmap->m_pAlphaMask ?
- (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop) + m_DestLeft : NULL;
- DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha, dest_alpha_scan);
-}
-void CFX_BitmapComposer::ComposeScanlineV(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
-{
- int i;
- int Bpp = m_pBitmap->GetBPP() / 8;
- int dest_pitch = m_pBitmap->GetPitch();
- int dest_alpha_pitch = m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0;
- int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line);
- FX_LPBYTE dest_buf = m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch;
- FX_LPBYTE dest_alpha_buf = m_pBitmap->m_pAlphaMask ?
- m_pBitmap->m_pAlphaMask->GetBuffer() + dest_x + m_DestTop * dest_alpha_pitch : NULL;
- if (m_bFlipY) {
- dest_buf += dest_pitch * (m_DestHeight - 1);
- dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1);
- }
- int y_step = dest_pitch;
- int y_alpha_step = dest_alpha_pitch;
- if (m_bFlipY) {
- y_step = -y_step;
- y_alpha_step = -y_alpha_step;
- }
- FX_LPBYTE src_scan = m_pScanlineV;
- FX_LPBYTE dest_scan = dest_buf;
- for (i = 0; i < m_DestHeight; i ++) {
- for (int j = 0; j < Bpp; j ++) {
- *src_scan++ = dest_scan[j];
- }
- dest_scan += y_step;
- }
- FX_LPBYTE src_alpha_scan = m_pScanlineAlphaV;
- FX_LPBYTE dest_alpha_scan = dest_alpha_buf;
- if (dest_alpha_scan) {
- for (i = 0; i < m_DestHeight; i ++) {
- *src_alpha_scan++ = *dest_alpha_scan;
- dest_alpha_scan += y_alpha_step;
- }
- }
- FX_LPBYTE clip_scan = NULL;
- if (m_pClipMask) {
- clip_scan = m_pClipScanV;
- int clip_pitch = m_pClipMask->GetPitch();
- FX_LPCBYTE src_clip = m_pClipMask->GetBuffer() + (m_DestTop - m_pClipRgn->GetBox().top) *
- clip_pitch + (dest_x - m_pClipRgn->GetBox().left);
- if (m_bFlipY) {
- src_clip += clip_pitch * (m_DestHeight - 1);
- clip_pitch = -clip_pitch;
- }
- for (i = 0; i < m_DestHeight; i ++) {
- clip_scan[i] = *src_clip;
- src_clip += clip_pitch;
- }
- }
- DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan, scan_extra_alpha, m_pScanlineAlphaV);
- src_scan = m_pScanlineV;
- dest_scan = dest_buf;
- for (i = 0; i < m_DestHeight; i ++) {
- for (int j = 0; j < Bpp; j ++) {
- dest_scan[j] = *src_scan++;
- }
- dest_scan += y_step;
- }
- src_alpha_scan = m_pScanlineAlphaV;
- dest_alpha_scan = dest_alpha_buf;
- if (dest_alpha_scan) {
- for (i = 0; i < m_DestHeight; i ++) {
- *dest_alpha_scan = *src_alpha_scan++;
- dest_alpha_scan += y_alpha_step;
- }
- }
-}
+// 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 "../../../include/fxge/fx_ge.h"
+#include "../../../include/fxcodec/fx_codec.h"
+#include "dib_int.h"
+const FX_BYTE g_GammaRamp[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
+ 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13,
+ 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 17, 18, 18, 19, 19, 20,
+ 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 29, 29,
+ 30, 30, 31, 32, 32, 33, 34, 35, 35, 36, 37, 37, 38, 39, 40, 41,
+ 41, 42, 43, 44, 45, 45, 46, 47, 48, 49, 50, 51, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88,
+ 90, 91, 92, 93, 95, 96, 97, 99, 100, 101, 103, 104, 105, 107, 108, 109,
+ 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, 125, 127, 128, 130, 131, 133,
+ 134, 136, 138, 139, 141, 142, 144, 146, 147, 149, 151, 152, 154, 156, 157, 159,
+ 161, 163, 164, 166, 168, 170, 171, 173, 175, 177, 179, 181, 183, 184, 186, 188,
+ 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220,
+ 222, 224, 226, 229, 231, 233, 235, 237, 239, 242, 244, 246, 248, 250, 253, 255,
+};
+const FX_BYTE g_GammaInverse[256] = {
+ 0, 13, 22, 28, 34, 38, 42, 46, 50, 53, 56, 59, 61, 64, 66, 69,
+ 71, 73, 75, 77, 79, 81, 83, 85, 86, 88, 90, 92, 93, 95, 96, 98,
+ 99, 101, 102, 104, 105, 106, 108, 109, 110, 112, 113, 114, 115, 117, 118, 119,
+ 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136,
+ 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 148, 149, 150, 151,
+ 152, 153, 154, 155, 155, 156, 157, 158, 159, 159, 160, 161, 162, 163, 163, 164,
+ 165, 166, 167, 167, 168, 169, 170, 170, 171, 172, 173, 173, 174, 175, 175, 176,
+ 177, 178, 178, 179, 180, 180, 181, 182, 182, 183, 184, 185, 185, 186, 187, 187,
+ 188, 189, 189, 190, 190, 191, 192, 192, 193, 194, 194, 195, 196, 196, 197, 197,
+ 198, 199, 199, 200, 200, 201, 202, 202, 203, 203, 204, 205, 205, 206, 206, 207,
+ 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, 214, 215, 215, 216,
+ 216, 217, 218, 218, 219, 219, 220, 220, 221, 221, 222, 222, 223, 223, 224, 224,
+ 225, 226, 226, 227, 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233,
+ 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 239, 239, 240, 240,
+ 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248,
+ 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 253, 253, 254, 254, 255, 255,
+};
+const FX_BYTE _color_sqrt[256] = {
+ 0x00, 0x03, 0x07, 0x0B, 0x0F, 0x12, 0x16, 0x19, 0x1D, 0x20, 0x23, 0x26, 0x29, 0x2C, 0x2F, 0x32,
+ 0x35, 0x37, 0x3A, 0x3C, 0x3F, 0x41, 0x43, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x50, 0x52, 0x54, 0x56,
+ 0x57, 0x59, 0x5B, 0x5C, 0x5E, 0x60, 0x61, 0x63, 0x64, 0x65, 0x67, 0x68, 0x69, 0x6B, 0x6C, 0x6D,
+ 0x6E, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E,
+ 0x8F, 0x90, 0x91, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C,
+ 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA4, 0xA5, 0xA6, 0xA7, 0xA7, 0xA8,
+ 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAD, 0xAE, 0xAF, 0xB0, 0xB0, 0xB1, 0xB2, 0xB3, 0xB3, 0xB4,
+ 0xB5, 0xB5, 0xB6, 0xB7, 0xB7, 0xB8, 0xB9, 0xBA, 0xBA, 0xBB, 0xBC, 0xBC, 0xBD, 0xBE, 0xBE, 0xBF,
+ 0xC0, 0xC0, 0xC1, 0xC2, 0xC2, 0xC3, 0xC4, 0xC4, 0xC5, 0xC6, 0xC6, 0xC7, 0xC7, 0xC8, 0xC9, 0xC9,
+ 0xCA, 0xCB, 0xCB, 0xCC, 0xCC, 0xCD, 0xCE, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, 0xD1, 0xD2, 0xD3, 0xD3,
+ 0xD4, 0xD4, 0xD5, 0xD6, 0xD6, 0xD7, 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDC, 0xDD,
+ 0xDD, 0xDE, 0xDE, 0xDF, 0xE0, 0xE0, 0xE1, 0xE1, 0xE2, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE5, 0xE6,
+ 0xE6, 0xE7, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEA, 0xEB, 0xEB, 0xEC, 0xEC, 0xED, 0xED, 0xEE, 0xEE,
+ 0xEF, 0xF0, 0xF0, 0xF1, 0xF1, 0xF2, 0xF2, 0xF3, 0xF3, 0xF4, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7,
+ 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF
+};
+int _BLEND(int blend_mode, int back_color, int src_color)
+{
+ switch (blend_mode) {
+ case FXDIB_BLEND_NORMAL:
+ return src_color;
+ case FXDIB_BLEND_MULTIPLY:
+ return src_color * back_color / 255;
+ case FXDIB_BLEND_SCREEN:
+ return src_color + back_color - src_color * back_color / 255;
+ case FXDIB_BLEND_OVERLAY:
+ return _BLEND(FXDIB_BLEND_HARDLIGHT, src_color, back_color);
+ case FXDIB_BLEND_DARKEN:
+ return src_color < back_color ? src_color : back_color;
+ case FXDIB_BLEND_LIGHTEN:
+ return src_color > back_color ? src_color : back_color;
+ case FXDIB_BLEND_COLORDODGE: {
+ if (src_color == 255) {
+ return src_color;
+ }
+ int result = back_color * 255 / (255 - src_color);
+ if (result > 255) {
+ return 255;
+ }
+ return result;
+ }
+ case FXDIB_BLEND_COLORBURN: {
+ if (src_color == 0) {
+ return src_color;
+ }
+ int result = (255 - back_color) * 255 / src_color;
+ if (result > 255) {
+ result = 255;
+ }
+ return 255 - result;
+ }
+ case FXDIB_BLEND_HARDLIGHT:
+ if (src_color < 128) {
+ return (src_color * back_color * 2) / 255;
+ }
+ return _BLEND(FXDIB_BLEND_SCREEN, back_color, 2 * src_color - 255);
+ case FXDIB_BLEND_SOFTLIGHT: {
+ if (src_color < 128) {
+ return back_color - (255 - 2 * src_color) * back_color * (255 - back_color) / 255 / 255;
+ }
+ return back_color + (2 * src_color - 255) * (_color_sqrt[back_color] - back_color) / 255;
+ }
+ case FXDIB_BLEND_DIFFERENCE:
+ return back_color < src_color ? src_color - back_color : back_color - src_color;
+ case FXDIB_BLEND_EXCLUSION:
+ return back_color + src_color - 2 * back_color * src_color / 255;
+ }
+ return src_color;
+}
+struct _RGB {
+ int red;
+ int green;
+ int blue;
+};
+static inline int _Lum(_RGB color)
+{
+ return (color.red * 30 + color.green * 59 + color.blue * 11) / 100;
+}
+static _RGB _ClipColor(_RGB color)
+{
+ int l = _Lum(color);
+ int n = color.red;
+ if (color.green < n) {
+ n = color.green;
+ }
+ if (color.blue < n) {
+ n = color.blue;
+ }
+ int x = color.red;
+ if (color.green > x) {
+ x = color.green;
+ }
+ if (color.blue > x) {
+ x = color.blue;
+ }
+ if (n < 0) {
+ color.red = l + ((color.red - l) * l / (l - n));
+ color.green = l + ((color.green - l) * l / (l - n));
+ color.blue = l + ((color.blue - l) * l / (l - n));
+ }
+ if (x > 255) {
+ color.red = l + ((color.red - l) * (255 - l) / (x - l));
+ color.green = l + ((color.green - l) * (255 - l) / (x - l));
+ color.blue = l + ((color.blue - l) * (255 - l) / (x - l));
+ }
+ return color;
+}
+static _RGB _SetLum(_RGB color, int l)
+{
+ int d = l - _Lum(color);
+ color.red += d;
+ color.green += d;
+ color.blue += d;
+ return _ClipColor(color);
+}
+static int _Sat(_RGB color)
+{
+ int n = color.red;
+ if (color.green < n) {
+ n = color.green;
+ }
+ if (color.blue < n) {
+ n = color.blue;
+ }
+ int x = color.red;
+ if (color.green > x) {
+ x = color.green;
+ }
+ if (color.blue > x) {
+ x = color.blue;
+ }
+ return x - n;
+}
+static _RGB _SetSat(_RGB color, int s)
+{
+ int* max = &color.red;
+ int* mid = &color.red;
+ int* min = &color.red;
+ if (color.green > *max) {
+ max = &color.green;
+ }
+ if (color.blue > *max) {
+ max = &color.blue;
+ }
+ if (color.green < *min) {
+ min = &color.green;
+ }
+ if (color.blue < *min) {
+ min = &color.blue;
+ }
+ if (*max == *min) {
+ color.red = 0;
+ color.green = 0;
+ color.blue = 0;
+ return color;
+ }
+ if (max == &color.red) {
+ if (min == &color.green) {
+ mid = &color.blue;
+ } else {
+ mid = &color.green;
+ }
+ } else if (max == &color.green) {
+ if (min == &color.red) {
+ mid = &color.blue;
+ } else {
+ mid = &color.red;
+ }
+ } else {
+ if (min == &color.green) {
+ mid = &color.red;
+ } else {
+ mid = &color.green;
+ }
+ }
+ if (*max > *min) {
+ *mid = (*mid - *min) * s / (*max - *min);
+ *max = s;
+ *min = 0;
+ }
+ return color;
+}
+void _RGB_Blend(int blend_mode, FX_LPCBYTE src_scan, FX_BYTE* dest_scan, int results[3])
+{
+ _RGB src, back, result;
+ src.red = src_scan[2];
+ src.green = src_scan[1];
+ src.blue = src_scan[0];
+ back.red = dest_scan[2];
+ back.green = dest_scan[1];
+ back.blue = dest_scan[0];
+ switch (blend_mode) {
+ case FXDIB_BLEND_HUE:
+ result = _SetLum(_SetSat(src, _Sat(back)), _Lum(back));
+ break;
+ case FXDIB_BLEND_SATURATION:
+ result = _SetLum(_SetSat(back, _Sat(src)), _Lum(back));
+ break;
+ case FXDIB_BLEND_COLOR:
+ result = _SetLum(src, _Lum(back));
+ break;
+ case FXDIB_BLEND_LUMINOSITY:
+ result = _SetLum(back, _Lum(src));
+ break;
+ }
+ results[0] = result.blue;
+ results[1] = result.green;
+ results[2] = result.red;
+}
+inline void _CompositeRow_Argb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, FX_LPCBYTE clip_scan)
+{
+ src_scan += 3;
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha = *src_scan;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ FX_BYTE back_alpha = *dest_scan;
+ if (!back_alpha) {
+ *dest_scan = src_alpha;
+ } else if (src_alpha) {
+ *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ }
+ dest_scan ++;
+ src_scan += 4;
+ }
+}
+void _CompositeRow_Rgba2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_alpha_scan, int pixel_count, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ FX_BYTE back_alpha = *dest_scan;
+ if (!back_alpha) {
+ *dest_scan = src_alpha;
+ } else if (src_alpha) {
+ *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ }
+ dest_scan ++;
+ }
+}
+void _CompositeRow_Rgb2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan)
+{
+ if (clip_scan) {
+ for (int i = 0; i < width; i ++) {
+ *dest_scan = FXDIB_ALPHA_UNION(*dest_scan, *clip_scan);
+ dest_scan ++;
+ clip_scan ++;
+ }
+ } else {
+ FXSYS_memset8(dest_scan, 0xff, width);
+ }
+}
+void _CompositeRow_Argb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_alpha_scan, FX_LPBYTE dst_alpha_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = NULL;
+ if (pIccTransform) {
+ pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ }
+ if (blend_type) {
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int blended_color;
+ if (src_alpha_scan) {
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE back_alpha = *dst_alpha_scan;
+ if (back_alpha == 0) {
+ int src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
+ } else {
+ *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dst_alpha_scan = src_alpha;
+ }
+ dest_scan ++;
+ dst_alpha_scan ++;
+ src_scan += 3;
+ continue;
+ }
+ FX_BYTE src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dst_alpha_scan ++;
+ src_scan += 3;
+ continue;
+ }
+ *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
+ int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
+ FX_BYTE gray;
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ dst_alpha_scan++;
+ src_scan += 3;
+ }
+ } else
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE back_alpha = *dst_alpha_scan;
+ if (back_alpha == 0) {
+ int src_alpha = src_scan[3];
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
+ } else {
+ *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dst_alpha_scan = src_alpha;
+ }
+ dest_scan ++;
+ dst_alpha_scan ++;
+ src_scan += 4;
+ continue;
+ }
+ FX_BYTE src_alpha = src_scan[3];
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dst_alpha_scan ++;
+ src_scan += 4;
+ continue;
+ }
+ *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
+ int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
+ FX_BYTE gray;
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ dst_alpha_scan++;
+ src_scan += 4;
+ }
+ return;
+ }
+ if (src_alpha_scan) {
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE back_alpha = *dst_alpha_scan;
+ if (back_alpha == 0) {
+ int src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
+ } else {
+ *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dst_alpha_scan = src_alpha;
+ }
+ dest_scan ++;
+ dst_alpha_scan ++;
+ src_scan += 3;
+ continue;
+ }
+ FX_BYTE src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dst_alpha_scan ++;
+ src_scan += 3;
+ continue;
+ }
+ *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
+ int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
+ FX_BYTE gray;
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ dst_alpha_scan++;
+ src_scan += 3;
+ }
+ } else
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE back_alpha = *dst_alpha_scan;
+ if (back_alpha == 0) {
+ int src_alpha = src_scan[3];
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
+ } else {
+ *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dst_alpha_scan = src_alpha;
+ }
+ dest_scan ++;
+ dst_alpha_scan ++;
+ src_scan += 4;
+ continue;
+ }
+ FX_BYTE src_alpha = src_scan[3];
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dst_alpha_scan ++;
+ src_scan += 4;
+ continue;
+ }
+ *dst_alpha_scan = FXDIB_ALPHA_UNION(back_alpha, src_alpha);
+ int alpha_ratio = src_alpha * 255 / (*dst_alpha_scan);
+ FX_BYTE gray;
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ dst_alpha_scan++;
+ src_scan += 4;
+ }
+}
+inline void _CompositeRow_Argb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count,
+ int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_alpha_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = NULL;
+ FX_BYTE gray;
+ if (pIccTransform) {
+ pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ }
+ if (blend_type) {
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int blended_color;
+ if (src_alpha_scan) {
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
+ }
+ dest_scan ++;
+ src_scan += 3;
+ }
+ } else
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha = src_scan[3];
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
+ }
+ dest_scan ++;
+ src_scan += 4;
+ }
+ return;
+ }
+ if (src_alpha_scan) {
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
+ }
+ dest_scan ++;
+ src_scan += 3;
+ }
+ } else
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha = src_scan[3];
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
+ }
+ dest_scan ++;
+ src_scan += 4;
+ }
+}
+inline void _CompositeRow_Rgb2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
+ int blend_type, FX_LPCBYTE clip_scan,
+ void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = NULL;
+ FX_BYTE gray;
+ if (pIccTransform) {
+ pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ }
+ if (blend_type) {
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int blended_color;
+ for (int col = 0; col < pixel_count; col ++) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ if (clip_scan && clip_scan[col] < 255) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
+ } else {
+ *dest_scan = gray;
+ }
+ dest_scan ++;
+ src_scan += src_Bpp;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ if (clip_scan && clip_scan[col] < 255) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
+ } else {
+ *dest_scan = gray;
+ }
+ dest_scan ++;
+ src_scan += src_Bpp;
+ }
+}
+void _CompositeRow_Rgb2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_Bpp, int pixel_count,
+ int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = NULL;
+ if (pIccTransform) {
+ pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ }
+ if (blend_type) {
+ int blended_color;
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ for (int col = 0; col < pixel_count; col ++) {
+ int back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
+ } else {
+ *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ dest_scan ++;
+ dest_alpha_scan++;
+ src_scan += src_Bpp;
+ continue;
+ }
+ int src_alpha = 255;
+ if (clip_scan) {
+ src_alpha = clip_scan[col];
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ src_scan += src_Bpp;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ FX_BYTE gray;
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ src_scan += src_Bpp;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha = 255;
+ if (clip_scan) {
+ src_alpha = clip_scan[col];
+ }
+ if (src_alpha == 255) {
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
+ } else {
+ *dest_scan = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ dest_scan ++;
+ *dest_alpha_scan++ = 255;
+ src_scan += src_Bpp;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ src_scan += src_Bpp;
+ continue;
+ }
+ int back_alpha = *dest_alpha_scan;
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ FX_BYTE gray;
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, &gray, src_scan, 1);
+ } else {
+ gray = FXRGB2GRAY(src_scan[2], src_scan[1], *src_scan);
+ }
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ src_scan += src_Bpp;
+ }
+}
+void _CompositeRow_Argb2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ if (dest_alpha_scan == NULL) {
+ if (src_alpha_scan == NULL) {
+ FX_BYTE back_alpha = 0;
+ for (int col = 0; col < pixel_count; col ++) {
+ back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ if (clip_scan) {
+ int src_alpha = clip_scan[col] * src_scan[3] / 255;
+ FXARGB_SETDIB(dest_scan, (FXARGB_GETDIB(src_scan) & 0xffffff) | (src_alpha << 24));
+ } else {
+ FXARGB_COPY(dest_scan, src_scan);
+ }
+ dest_scan += 4;
+ src_scan += 4;
+ continue;
+ }
+ FX_BYTE src_alpha;
+ if (clip_scan == NULL) {
+ src_alpha = src_scan[3];
+ } else {
+ src_alpha = clip_scan[col] * src_scan[3] / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ src_scan += 4;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ if (blend_type) {
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, *dest_scan, *src_scan);
+ blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
+ }
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan ++;
+ src_scan ++;
+ }
+ } else {
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ if (clip_scan) {
+ int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE((src_alpha << 24), src_scan[2], src_scan[1], *src_scan));
+ } else {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE((*src_alpha_scan << 24), src_scan[2], src_scan[1], *src_scan));
+ }
+ dest_scan += 4;
+ src_scan += 3;
+ src_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE src_alpha;
+ if (clip_scan == NULL) {
+ src_alpha = *src_alpha_scan ++;
+ } else {
+ src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ if (blend_type) {
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, *dest_scan, *src_scan);
+ blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
+ }
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan ++;
+ }
+ }
+ } else {
+ if (src_alpha_scan) {
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ if (clip_scan) {
+ int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
+ *dest_alpha_scan = src_alpha;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ } else {
+ *dest_alpha_scan = *src_alpha_scan;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ }
+ dest_alpha_scan ++;
+ src_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE src_alpha;
+ if (clip_scan == NULL) {
+ src_alpha = *src_alpha_scan ++;
+ } else {
+ src_alpha = clip_scan[col] * (*src_alpha_scan ++) / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 3;
+ src_scan += 3;
+ dest_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ if (blend_type) {
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, *dest_scan, *src_scan);
+ blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
+ }
+ dest_scan ++;
+ src_scan ++;
+ }
+ }
+ } else {
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ if (clip_scan) {
+ int src_alpha = clip_scan[col] * src_scan[3] / 255;
+ *dest_alpha_scan = src_alpha;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ } else {
+ *dest_alpha_scan = src_scan[3];
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ }
+ dest_alpha_scan ++;
+ src_scan ++;
+ continue;
+ }
+ FX_BYTE src_alpha;
+ if (clip_scan == NULL) {
+ src_alpha = src_scan[3];
+ } else {
+ src_alpha = clip_scan[col] * src_scan[3] / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 3;
+ src_scan += 4;
+ dest_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ if (blend_type) {
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, *dest_scan, *src_scan);
+ blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
+ }
+ dest_scan ++;
+ src_scan ++;
+ }
+ src_scan ++;
+ }
+ }
+ }
+}
+void _CompositeRow_Rgb2Argb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
+ FX_LPBYTE dest_alpha_scan)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int src_gap = src_Bpp - 3;
+ if (dest_alpha_scan == NULL) {
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ if (src_Bpp == 4) {
+ FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
+ } else {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
+ }
+ dest_scan += 4;
+ src_scan += src_Bpp;
+ continue;
+ }
+ dest_scan[3] = 0xff;
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int src_color = *src_scan;
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, *dest_scan, src_color);
+ *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan ++;
+ src_scan += src_gap;
+ }
+ } else {
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_alpha_scan++ = 0xff;
+ src_scan += src_gap;
+ continue;
+ }
+ *dest_alpha_scan++ = 0xff;
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int src_color = *src_scan;
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, *dest_scan, src_color);
+ *dest_scan = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
+ dest_scan ++;
+ src_scan ++;
+ }
+ src_scan += src_gap;
+ }
+ }
+}
+inline void _CompositeRow_Rgb2Argb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int src_gap = src_Bpp - 3;
+ if (dest_alpha_scan == NULL) {
+ for (int col = 0; col < width; col ++) {
+ int src_alpha = *clip_scan ++;
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ src_scan += src_gap;
+ dest_scan ++;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ src_scan += src_Bpp;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int src_color = *src_scan;
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, *dest_scan, src_color);
+ blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan ++;
+ src_scan += src_gap;
+ }
+ } else {
+ for (int col = 0; col < width; col ++) {
+ int src_alpha = *clip_scan ++;
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ src_scan += src_gap;
+ dest_alpha_scan++;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 3;
+ dest_alpha_scan++;
+ src_scan += src_Bpp;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int src_color = *src_scan;
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, *dest_scan, src_color);
+ blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ src_scan ++;
+ }
+ src_scan += src_gap;
+ }
+ }
+}
+inline void _CompositeRow_Rgb2Argb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan)
+{
+ int src_gap = src_Bpp - 3;
+ if (dest_alpha_scan == NULL) {
+ for (int col = 0; col < width; col ++) {
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 255) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = 255;
+ src_scan += src_gap;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ src_scan += src_Bpp;
+ continue;
+ }
+ int back_alpha = dest_scan[3];
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ for (int color = 0; color < 3; color ++) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan ++;
+ src_scan += src_gap;
+ }
+ } else {
+ for (int col = 0; col < width; col ++) {
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 255) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_alpha_scan++ = 255;
+ src_scan += src_gap;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 3;
+ dest_alpha_scan ++;
+ src_scan += src_Bpp;
+ continue;
+ }
+ int back_alpha = *dest_alpha_scan;
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ for (int color = 0; color < 3; color ++) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, alpha_ratio);
+ dest_scan ++;
+ src_scan ++;
+ }
+ src_scan += src_gap;
+ }
+ }
+}
+inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
+ FX_LPBYTE dest_alpha_scan)
+{
+ if (dest_alpha_scan == NULL) {
+ for (int col = 0; col < width; col ++) {
+ if (src_Bpp == 4) {
+ FXARGB_SETDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
+ } else {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
+ }
+ dest_scan += 4;
+ src_scan += src_Bpp;
+ }
+ } else {
+ int src_gap = src_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_alpha_scan++ = 0xff;
+ src_scan += src_gap;
+ }
+ }
+}
+inline void _CompositeRow_Argb2Rgb_Blend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_alpha_scan)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int dest_gap = dest_Bpp - 3;
+ if (src_alpha_scan == NULL) {
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE src_alpha;
+ if (clip_scan) {
+ src_alpha = src_scan[3] * (*clip_scan++) / 255;
+ } else {
+ src_alpha = src_scan[3];
+ }
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_scan += 4;
+ continue;
+ }
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int back_color = *dest_scan;
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, back_color, *src_scan);
+ *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan += dest_gap;
+ src_scan ++;
+ }
+ } else {
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE src_alpha;
+ if (clip_scan) {
+ src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
+ } else {
+ src_alpha = *src_alpha_scan++;
+ }
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_scan += 3;
+ continue;
+ }
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int back_color = *dest_scan;
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, back_color, *src_scan);
+ *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan += dest_gap;
+ }
+ }
+}
+inline void _CompositeRow_Argb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_alpha_scan)
+{
+ int dest_gap = dest_Bpp - 3;
+ if (src_alpha_scan == NULL) {
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE src_alpha;
+ if (clip_scan) {
+ src_alpha = src_scan[3] * (*clip_scan++) / 255;
+ } else {
+ src_alpha = src_scan[3];
+ }
+ if (src_alpha == 255) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ dest_scan += dest_gap;
+ src_scan ++;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_scan += 4;
+ continue;
+ }
+ for (int color = 0; color < 3; color ++) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan += dest_gap;
+ src_scan ++;
+ }
+ } else {
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE src_alpha;
+ if (clip_scan) {
+ src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
+ } else {
+ src_alpha = *src_alpha_scan++;
+ }
+ if (src_alpha == 255) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ dest_scan += dest_gap;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_scan += 3;
+ continue;
+ }
+ for (int color = 0; color < 3; color ++) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan += dest_gap;
+ }
+ }
+}
+inline void _CompositeRow_Rgb2Rgb_Blend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int dest_gap = dest_Bpp - 3;
+ int src_gap = src_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int back_color = *dest_scan;
+ int src_color = *src_scan;
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, back_color, src_color);
+ *dest_scan = blended;
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan += dest_gap;
+ src_scan += src_gap;
+ }
+}
+inline void _CompositeRow_Rgb2Rgb_Blend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int dest_gap = dest_Bpp - 3;
+ int src_gap = src_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE src_alpha = *clip_scan ++;
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_scan += src_Bpp;
+ continue;
+ }
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int src_color = *src_scan;
+ int back_color = *dest_scan;
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, back_color, src_color);
+ *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
+ dest_scan ++;
+ src_scan ++;
+ }
+ dest_scan += dest_gap;
+ src_scan += src_gap;
+ }
+}
+inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
+{
+ if (dest_Bpp == src_Bpp) {
+ FXSYS_memcpy32(dest_scan, src_scan, width * dest_Bpp);
+ return;
+ }
+ for (int col = 0; col < width; col ++) {
+ dest_scan[0] = src_scan[0];
+ dest_scan[1] = src_scan[1];
+ dest_scan[2] = src_scan[2];
+ dest_scan += dest_Bpp;
+ src_scan += src_Bpp;
+ }
+}
+inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < width; col ++) {
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 255) {
+ dest_scan[0] = src_scan[0];
+ dest_scan[1] = src_scan[1];
+ dest_scan[2] = src_scan[2];
+ } else if (src_alpha) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
+ dest_scan ++;
+ src_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
+ dest_scan ++;
+ src_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_scan, src_alpha);
+ dest_scan += dest_Bpp - 2;
+ src_scan += src_Bpp - 2;
+ continue;
+ }
+ dest_scan += dest_Bpp;
+ src_scan += src_Bpp;
+ }
+}
+void _CompositeRow_Argb2Argb_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ FX_LPBYTE dp = src_cache_scan;
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_alpha_scan) {
+ if (dest_alpha_scan == NULL) {
+ for (int col = 0; col < pixel_count; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ dp[3] = *src_alpha_scan++;
+ src_scan += 3;
+ dp += 4;
+ }
+ src_alpha_scan = NULL;
+ } else {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, pixel_count);
+ }
+ } else {
+ if (dest_alpha_scan == NULL) {
+ for (int col = 0; col < pixel_count; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ dp[3] = src_scan[3];
+ src_scan += 4;
+ dp += 4;
+ }
+ } else {
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ for (int col = 0; col < pixel_count; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ if (clip_scan) {
+ int src_alpha = clip_scan[col] * src_scan[3] / 255;
+ *dest_alpha_scan = src_alpha;
+ *dest_scan++ = *src_cache_scan++;
+ *dest_scan++ = *src_cache_scan++;
+ *dest_scan++ = *src_cache_scan++;
+ } else {
+ *dest_alpha_scan = src_scan[3];
+ *dest_scan++ = *src_cache_scan++;
+ *dest_scan++ = *src_cache_scan++;
+ *dest_scan++ = *src_cache_scan++;
+ }
+ dest_alpha_scan ++;
+ src_scan += 4;
+ continue;
+ }
+ FX_BYTE src_alpha;
+ if (clip_scan == NULL) {
+ src_alpha = src_scan[3];
+ } else {
+ src_alpha = clip_scan[col] * src_scan[3] / 255;
+ }
+ src_scan += 4;
+ if (src_alpha == 0) {
+ dest_scan += 3;
+ src_cache_scan += 3;
+ dest_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ if (blend_type) {
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, *dest_scan, *src_cache_scan);
+ blended = FXDIB_ALPHA_MERGE(*src_cache_scan, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, alpha_ratio);
+ }
+ dest_scan ++;
+ src_cache_scan ++;
+ }
+ }
+ return;
+ }
+ }
+ _CompositeRow_Argb2Argb(dest_scan, src_cache_scan, pixel_count, blend_type, clip_scan, dest_alpha_scan, src_alpha_scan);
+}
+void _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp,
+ FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_Bpp == 3) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ FX_LPBYTE dp = src_cache_scan;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ src_scan += 4;
+ dp += 3;
+ }
+ }
+ _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, 3, dest_alpha_scan);
+}
+inline void _CompositeRow_Rgb2Argb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_Bpp == 3) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ FX_LPBYTE dp = src_cache_scan;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ src_scan += 4;
+ dp += 3;
+ }
+ }
+ _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, 3, clip_scan, dest_alpha_scan);
+}
+inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_Bpp == 3) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ FX_LPBYTE dp = src_cache_scan;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ src_scan += 4;
+ dp += 3;
+ }
+ }
+ _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_cache_scan, width, 3, clip_scan, dest_alpha_scan);
+}
+inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp,
+ FX_LPBYTE dest_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_Bpp == 3) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ FX_LPBYTE dp = src_cache_scan;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ src_scan += 4;
+ dp += 3;
+ }
+ }
+ _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_cache_scan, width, 3, dest_alpha_scan);
+}
+inline void _CompositeRow_Argb2Rgb_Blend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_alpha_scan) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int dest_gap = dest_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
+ FX_BYTE src_alpha;
+ if (clip_scan) {
+ src_alpha = src_scan[3] * (*clip_scan++) / 255;
+ } else {
+ src_alpha = src_scan[3];
+ }
+ src_scan += 4;
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_cache_scan += 3;
+ continue;
+ }
+ if (bNonseparableBlend) {
+ _RGB_Blend(blend_type, src_cache_scan, dest_scan, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int back_color = *dest_scan;
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, back_color, *src_cache_scan);
+ *dest_scan = FXDIB_ALPHA_MERGE(back_color, blended, src_alpha);
+ dest_scan ++;
+ src_cache_scan ++;
+ }
+ dest_scan += dest_gap;
+ }
+ return;
+ }
+ _CompositeRow_Argb2Rgb_Blend(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, clip_scan, src_alpha_scan);
+}
+inline void _CompositeRow_Argb2Rgb_NoBlend_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_alpha_scan, FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_alpha_scan) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ int dest_gap = dest_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, 1);
+ FX_BYTE src_alpha;
+ if (clip_scan) {
+ src_alpha = src_scan[3] * (*clip_scan++) / 255;
+ } else {
+ src_alpha = src_scan[3];
+ }
+ src_scan += 4;
+ if (src_alpha == 255) {
+ *dest_scan++ = *src_cache_scan++;
+ *dest_scan++ = *src_cache_scan++;
+ *dest_scan++ = *src_cache_scan++;
+ dest_scan += dest_gap;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_cache_scan += 3;
+ continue;
+ }
+ for (int color = 0; color < 3; color ++) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, *src_cache_scan, src_alpha);
+ dest_scan ++;
+ src_cache_scan ++;
+ }
+ dest_scan += dest_gap;
+ }
+ return;
+ }
+ _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_cache_scan, width, dest_Bpp, clip_scan, src_alpha_scan);
+}
+inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp,
+ FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_Bpp == 3) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ FX_LPBYTE dp = src_cache_scan;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ src_scan += 4;
+ dp += 3;
+ }
+ }
+ _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3);
+}
+inline void _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_Bpp == 3) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ FX_LPBYTE dp = src_cache_scan;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ src_scan += 4;
+ dp += 3;
+ }
+ }
+ _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_cache_scan, width, blend_type, dest_Bpp, 3, clip_scan);
+}
+inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp,
+ FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_Bpp == 3) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ FX_LPBYTE dp = src_cache_scan;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ src_scan += 4;
+ dp += 3;
+ }
+ }
+ _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_cache_scan, width, dest_Bpp, 3);
+}
+inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan,
+ FX_LPBYTE src_cache_scan, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (src_Bpp == 3) {
+ pIccModule->TranslateScanline(pIccTransform, src_cache_scan, src_scan, width);
+ } else {
+ FX_LPBYTE dp = src_cache_scan;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dp, src_scan, 1);
+ src_scan += 4;
+ dp += 3;
+ }
+ }
+ _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_cache_scan, width, dest_Bpp, 3, clip_scan);
+}
+inline void _CompositeRow_8bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
+ int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_alpha_scan)
+{
+ if (src_alpha_scan) {
+ if (blend_type) {
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int blended_color;
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = pPalette[*src_scan];
+ int src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ if (src_alpha) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
+ } else {
+ *dest_scan = gray;
+ }
+ dest_scan ++;
+ src_scan ++;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = pPalette[*src_scan];
+ int src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
+ } else {
+ *dest_scan = gray;
+ }
+ dest_scan ++;
+ src_scan ++;
+ }
+ } else {
+ if (blend_type) {
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int blended_color;
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = pPalette[*src_scan];
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ if (clip_scan && clip_scan[col] < 255) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
+ } else {
+ *dest_scan = gray;
+ }
+ dest_scan ++;
+ src_scan ++;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = pPalette[*src_scan];
+ if (clip_scan && clip_scan[col] < 255) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
+ } else {
+ *dest_scan = gray;
+ }
+ dest_scan ++;
+ src_scan ++;
+ }
+ }
+}
+inline void _CompositeRow_8bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_LPCBYTE pPalette, int pixel_count,
+ int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
+{
+ if (src_alpha_scan) {
+ if (blend_type) {
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int blended_color;
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = pPalette[*src_scan];
+ src_scan ++;
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ int src_alpha = *src_alpha_scan ++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ *dest_scan = gray;
+ *dest_alpha_scan = src_alpha;
+ }
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_alpha_scan ++;
+ dest_scan ++;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = pPalette[*src_scan];
+ src_scan ++;
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ int src_alpha = *src_alpha_scan ++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha) {
+ *dest_scan = gray;
+ *dest_alpha_scan = src_alpha;
+ }
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE src_alpha = *src_alpha_scan++;
+ if (clip_scan) {
+ src_alpha = clip_scan[col] * src_alpha / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ *dest_alpha_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ int alpha_ratio = src_alpha * 255 / (*dest_alpha_scan);
+ dest_alpha_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ }
+ } else {
+ if (blend_type) {
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int blended_color;
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = pPalette[*src_scan];
+ src_scan ++;
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ *dest_scan++ = gray;
+ *dest_alpha_scan++ = 255;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ int back_alpha = *dest_alpha_scan;
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = pPalette[*src_scan];
+ src_scan ++;
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ *dest_scan++ = gray;
+ *dest_alpha_scan++ = 255;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ int back_alpha = *dest_alpha_scan;
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ }
+ }
+}
+inline void _CompositeRow_1bppPal2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
+ FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
+{
+ int reset_gray = pPalette[0];
+ int set_gray = pPalette[1];
+ if (blend_type) {
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int blended_color;
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ if (clip_scan && clip_scan[col] < 255) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
+ } else {
+ *dest_scan = gray;
+ }
+ dest_scan ++;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
+ if (clip_scan && clip_scan[col] < 255) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, clip_scan[col]);
+ } else {
+ *dest_scan = gray;
+ }
+ dest_scan ++;
+ }
+}
+inline void _CompositeRow_1bppPal2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
+ FX_LPCBYTE pPalette, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan)
+{
+ int reset_gray = pPalette[0];
+ int set_gray = pPalette[1];
+ if (blend_type) {
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int blended_color;
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ *dest_scan++ = gray;
+ *dest_alpha_scan ++ = 255;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ int back_alpha = *dest_alpha_scan;
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ blended_color = blend_type == FXDIB_BLEND_LUMINOSITY ? gray : *dest_scan;
+ }
+ gray = bNonseparableBlend ? blended_color : _BLEND(blend_type, *dest_scan, gray);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE gray = (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) ? set_gray : reset_gray;
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ *dest_scan++ = gray;
+ *dest_alpha_scan ++ = 255;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ int back_alpha = *dest_alpha_scan;
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, alpha_ratio);
+ dest_scan ++;
+ }
+}
+inline void _CompositeRow_8bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_DWORD* pPalette, int pixel_count,
+ int DestBpp, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_alpha_scan)
+{
+ if (src_alpha_scan) {
+ int dest_gap = DestBpp - 3;
+ FX_ARGB argb = 0;
+ for (int col = 0; col < pixel_count; col ++) {
+ argb = pPalette[*src_scan];
+ int src_r = FXARGB_R(argb);
+ int src_g = FXARGB_G(argb);
+ int src_b = FXARGB_B(argb);
+ src_scan ++;
+ FX_BYTE src_alpha = 0;
+ if (clip_scan) {
+ src_alpha = (*src_alpha_scan++) * (*clip_scan++) / 255;
+ } else {
+ src_alpha = *src_alpha_scan++;
+ }
+ if (src_alpha == 255) {
+ *dest_scan++ = src_b;
+ *dest_scan++ = src_g;
+ *dest_scan++ = src_r;
+ dest_scan += dest_gap;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += DestBpp;
+ continue;
+ }
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
+ dest_scan ++;
+ dest_scan += dest_gap;
+ }
+ } else {
+ FX_ARGB argb = 0;
+ for (int col = 0; col < pixel_count; col ++) {
+ argb = pPalette[*src_scan];
+ int src_r = FXARGB_R(argb);
+ int src_g = FXARGB_G(argb);
+ int src_b = FXARGB_B(argb);
+ if (clip_scan && clip_scan[col] < 255) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
+ dest_scan ++;
+ } else {
+ *dest_scan++ = src_b;
+ *dest_scan++ = src_g;
+ *dest_scan++ = src_r;
+ }
+ if (DestBpp == 4) {
+ dest_scan++;
+ }
+ src_scan ++;
+ }
+ }
+}
+inline void _CompositeRow_1bppRgb2Rgb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
+ FX_DWORD* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
+{
+ int reset_r, reset_g, reset_b;
+ int set_r, set_g, set_b;
+ reset_r = FXARGB_R(pPalette[0]);
+ reset_g = FXARGB_G(pPalette[0]);
+ reset_b = FXARGB_B(pPalette[0]);
+ set_r = FXARGB_R(pPalette[1]);
+ set_g = FXARGB_G(pPalette[1]);
+ set_b = FXARGB_B(pPalette[1]);
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_r, src_g, src_b;
+ if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
+ src_r = set_r;
+ src_g = set_g;
+ src_b = set_b;
+ } else {
+ src_r = reset_r;
+ src_g = reset_g;
+ src_b = reset_b;
+ }
+ if (clip_scan && clip_scan[col] < 255) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, clip_scan[col]);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, clip_scan[col]);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, clip_scan[col]);
+ dest_scan ++;
+ } else {
+ *dest_scan++ = src_b;
+ *dest_scan++ = src_g;
+ *dest_scan++ = src_r;
+ }
+ if (DestBpp == 4) {
+ dest_scan++;
+ }
+ }
+}
+inline void _CompositeRow_8bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
+ FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_alpha_scan)
+{
+ if (src_alpha_scan) {
+ for (int col = 0; col < width; col ++) {
+ FX_ARGB argb = pPalette[*src_scan];
+ src_scan ++;
+ int src_r = FXARGB_R(argb);
+ int src_g = FXARGB_G(argb);
+ int src_b = FXARGB_B(argb);
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ if (clip_scan) {
+ int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
+ } else {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(*src_alpha_scan, src_r, src_g, src_b));
+ }
+ dest_scan += 4;
+ src_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE src_alpha;
+ if (clip_scan == NULL) {
+ src_alpha = *src_alpha_scan ++;
+ } else {
+ src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ dest_scan ++;
+ dest_scan ++;
+ }
+ } else
+ for (int col = 0; col < width; col ++) {
+ FX_ARGB argb = pPalette[*src_scan];
+ int src_r = FXARGB_R(argb);
+ int src_g = FXARGB_G(argb);
+ int src_b = FXARGB_B(argb);
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ *dest_scan++ = src_b;
+ *dest_scan++ = src_g;
+ *dest_scan++ = src_r;
+ *dest_scan++ = 255;
+ src_scan ++;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ src_scan ++;
+ continue;
+ }
+ int back_alpha = dest_scan[3];
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ dest_scan ++;
+ dest_scan ++;
+ src_scan ++;
+ }
+}
+void _CompositeRow_8bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
+ FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan, FX_LPCBYTE src_alpha_scan)
+{
+ if (src_alpha_scan) {
+ for (int col = 0; col < width; col ++) {
+ FX_ARGB argb = pPalette[*src_scan];
+ src_scan ++;
+ int src_r = FXARGB_R(argb);
+ int src_g = FXARGB_G(argb);
+ int src_b = FXARGB_B(argb);
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ if (clip_scan) {
+ int src_alpha = clip_scan[col] * (*src_alpha_scan) / 255;
+ *dest_alpha_scan ++ = src_alpha;
+ } else {
+ *dest_alpha_scan ++ = *src_alpha_scan;
+ }
+ *dest_scan ++ = src_b;
+ *dest_scan ++ = src_g;
+ *dest_scan ++ = src_r;
+ src_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE src_alpha;
+ if (clip_scan == NULL) {
+ src_alpha = *src_alpha_scan++;
+ } else {
+ src_alpha = clip_scan[col] * (*src_alpha_scan++) / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 3;
+ dest_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ dest_scan ++;
+ }
+ } else
+ for (int col = 0; col < width; col ++) {
+ FX_ARGB argb = pPalette[*src_scan];
+ int src_r = FXARGB_R(argb);
+ int src_g = FXARGB_G(argb);
+ int src_b = FXARGB_B(argb);
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ *dest_scan++ = src_b;
+ *dest_scan++ = src_g;
+ *dest_scan++ = src_r;
+ *dest_alpha_scan++ = 255;
+ src_scan ++;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan += 3;
+ dest_alpha_scan ++;
+ src_scan ++;
+ continue;
+ }
+ int back_alpha = *dest_alpha_scan;
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ dest_scan ++;
+ src_scan ++;
+ }
+}
+inline void _CompositeRow_1bppRgb2Argb_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
+ FX_DWORD* pPalette, FX_LPCBYTE clip_scan)
+{
+ int reset_r, reset_g, reset_b;
+ int set_r, set_g, set_b;
+ reset_r = FXARGB_R(pPalette[0]);
+ reset_g = FXARGB_G(pPalette[0]);
+ reset_b = FXARGB_B(pPalette[0]);
+ set_r = FXARGB_R(pPalette[1]);
+ set_g = FXARGB_G(pPalette[1]);
+ set_b = FXARGB_B(pPalette[1]);
+ for (int col = 0; col < width; col ++) {
+ int src_r, src_g, src_b;
+ if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
+ src_r = set_r;
+ src_g = set_g;
+ src_b = set_b;
+ } else {
+ src_r = reset_r;
+ src_g = reset_g;
+ src_b = reset_b;
+ }
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ *dest_scan++ = src_b;
+ *dest_scan++ = src_g;
+ *dest_scan++ = src_r;
+ *dest_scan++ = 255;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ continue;
+ }
+ int back_alpha = dest_scan[3];
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ dest_scan ++;
+ dest_scan ++;
+ }
+}
+void _CompositeRow_1bppRgb2Rgba_NoBlend(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
+ FX_DWORD* pPalette, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan)
+{
+ int reset_r, reset_g, reset_b;
+ int set_r, set_g, set_b;
+ reset_r = FXARGB_R(pPalette[0]);
+ reset_g = FXARGB_G(pPalette[0]);
+ reset_b = FXARGB_B(pPalette[0]);
+ set_r = FXARGB_R(pPalette[1]);
+ set_g = FXARGB_G(pPalette[1]);
+ set_b = FXARGB_B(pPalette[1]);
+ for (int col = 0; col < width; col ++) {
+ int src_r, src_g, src_b;
+ if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
+ src_r = set_r;
+ src_g = set_g;
+ src_b = set_b;
+ } else {
+ src_r = reset_r;
+ src_g = reset_g;
+ src_b = reset_b;
+ }
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ *dest_scan++ = src_b;
+ *dest_scan++ = src_g;
+ *dest_scan++ = src_r;
+ *dest_alpha_scan++ = 255;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan += 3;
+ dest_alpha_scan ++;
+ continue;
+ }
+ int back_alpha = *dest_alpha_scan;
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ dest_scan ++;
+ }
+}
+void _CompositeRow_ByteMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
+ int blend_type, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
+ } else {
+ src_alpha = mask_alpha * src_scan[col] / 255;
+ }
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
+ dest_scan += 4;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
+ } else if (blend_type) {
+ int blended = _BLEND(blend_type, *dest_scan, src_b);
+ blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_g);
+ blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_r);
+ blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ }
+ dest_scan += 2;
+ }
+}
+void _CompositeRow_ByteMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
+ int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
+ } else {
+ src_alpha = mask_alpha * src_scan[col] / 255;
+ }
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ *dest_scan ++ = src_b;
+ *dest_scan ++ = src_g;
+ *dest_scan ++ = src_r;
+ *dest_alpha_scan ++ = src_alpha;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 3;
+ dest_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
+ dest_scan ++;
+ } else if (blend_type) {
+ int blended = _BLEND(blend_type, *dest_scan, src_b);
+ blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_g);
+ blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_r);
+ blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ dest_scan ++;
+ }
+ }
+}
+void _CompositeRow_ByteMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
+ int blend_type, int Bpp, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
+ } else {
+ src_alpha = mask_alpha * src_scan[col] / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan += Bpp;
+ continue;
+ }
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
+ } else if (blend_type) {
+ int blended = _BLEND(blend_type, *dest_scan, src_b);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_g);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_r);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
+ }
+ dest_scan += Bpp - 2;
+ }
+}
+void _CompositeRow_ByteMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int pixel_count,
+ FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
+ } else {
+ src_alpha = mask_alpha * src_scan[col] / 255;
+ }
+ FX_BYTE back_alpha = *dest_scan;
+ if (!back_alpha) {
+ *dest_scan = src_alpha;
+ } else if (src_alpha) {
+ *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ }
+ dest_scan ++;
+ }
+}
+void _CompositeRow_ByteMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
+ int pixel_count, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
+ } else {
+ src_alpha = mask_alpha * src_scan[col] / 255;
+ }
+ if (src_alpha) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
+ }
+ dest_scan ++;
+ }
+}
+void _CompositeRow_ByteMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
+ int pixel_count, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
+ } else {
+ src_alpha = mask_alpha * src_scan[col] / 255;
+ }
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ *dest_scan ++ = src_gray;
+ *dest_alpha_scan ++ = src_alpha;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
+ dest_scan ++;
+ }
+}
+void _CompositeRow_BitMask2Argb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
+ int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
+{
+ if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
+ FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
+ for (int col = 0; col < pixel_count; col ++) {
+ if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
+ FXARGB_SETDIB(dest_scan, argb);
+ }
+ dest_scan += 4;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
+ dest_scan += 4;
+ continue;
+ }
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] / 255;
+ } else {
+ src_alpha = mask_alpha;
+ }
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
+ dest_scan += 4;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
+ } else if (blend_type) {
+ int blended = _BLEND(blend_type, *dest_scan, src_b);
+ blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_g);
+ blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_r);
+ blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ }
+ dest_scan += 2;
+ }
+}
+void _CompositeRow_BitMask2Rgba(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
+ int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan)
+{
+ if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
+ for (int col = 0; col < pixel_count; col ++) {
+ if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
+ dest_scan[0] = src_b;
+ dest_scan[1] = src_g;
+ dest_scan[2] = src_r;
+ *dest_alpha_scan = mask_alpha;
+ }
+ dest_scan += 3;
+ dest_alpha_scan ++;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
+ dest_scan += 3;
+ dest_alpha_scan ++;
+ continue;
+ }
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] / 255;
+ } else {
+ src_alpha = mask_alpha;
+ }
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ *dest_scan ++ = src_b;
+ *dest_scan ++ = src_g;
+ *dest_scan ++ = src_r;
+ *dest_alpha_scan ++ = mask_alpha;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], alpha_ratio);
+ dest_scan ++;
+ } else if (blend_type) {
+ int blended = _BLEND(blend_type, *dest_scan, src_b);
+ blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_g);
+ blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ blended = _BLEND(blend_type, *dest_scan, src_r);
+ blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, alpha_ratio);
+ dest_scan ++;
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
+ dest_scan ++;
+ }
+ }
+}
+void _CompositeRow_BitMask2Rgb(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
+ int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
+{
+ if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
+ for (int col = 0; col < pixel_count; col ++) {
+ if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
+ dest_scan[2] = src_r;
+ dest_scan[1] = src_g;
+ dest_scan[0] = src_b;
+ }
+ dest_scan += Bpp;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
+ dest_scan += Bpp;
+ continue;
+ }
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] / 255;
+ } else {
+ src_alpha = mask_alpha;
+ }
+ if (src_alpha == 0) {
+ dest_scan += Bpp;
+ continue;
+ }
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ _RGB_Blend(blend_type, src_scan, dest_scan, blended_colors);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[0], src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[1], src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended_colors[2], src_alpha);
+ } else if (blend_type) {
+ int blended = _BLEND(blend_type, *dest_scan, src_b);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
+ dest_scan++;
+ blended = _BLEND(blend_type, *dest_scan, src_g);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
+ dest_scan++;
+ blended = _BLEND(blend_type, *dest_scan, src_r);
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, blended, src_alpha);
+ } else {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, src_alpha);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, src_alpha);
+ }
+ dest_scan += Bpp - 2;
+ }
+}
+void _CompositeRow_BitMask2Mask(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_left,
+ int pixel_count, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
+ dest_scan ++;
+ continue;
+ }
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] / 255;
+ } else {
+ src_alpha = mask_alpha;
+ }
+ FX_BYTE back_alpha = *dest_scan;
+ if (!back_alpha) {
+ *dest_scan = src_alpha;
+ } else if (src_alpha) {
+ *dest_scan = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ }
+ dest_scan ++;
+ }
+}
+void _CompositeRow_BitMask2Gray(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
+ int src_left, int pixel_count, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
+ dest_scan ++;
+ continue;
+ }
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] / 255;
+ } else {
+ src_alpha = mask_alpha;
+ }
+ if (src_alpha) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, src_alpha);
+ }
+ dest_scan ++;
+ }
+}
+void _CompositeRow_BitMask2Graya(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_gray,
+ int src_left, int pixel_count, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dest_alpha_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] / 255;
+ } else {
+ src_alpha = mask_alpha;
+ }
+ FX_BYTE back_alpha = *dest_alpha_scan;
+ if (back_alpha == 0) {
+ *dest_scan ++ = src_gray;
+ *dest_alpha_scan ++ = src_alpha;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan ++;
+ dest_alpha_scan ++;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_alpha_scan++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_gray, alpha_ratio);
+ dest_scan ++;
+ }
+}
+void _CompositeRow_Argb2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ if (clip_scan) {
+ int src_alpha = clip_scan[col] * src_scan[3] / 255;
+ dest_scan[3] = src_alpha;
+ dest_scan[0] = src_scan[2];
+ dest_scan[1] = src_scan[1];
+ dest_scan[2] = src_scan[0];
+ } else {
+ FXARGB_RGBORDERCOPY(dest_scan, src_scan);
+ }
+ dest_scan += 4;
+ src_scan += 4;
+ continue;
+ }
+ FX_BYTE src_alpha;
+ if (clip_scan == NULL) {
+ src_alpha = src_scan[3];
+ } else {
+ src_alpha = clip_scan[col] * src_scan[3] / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ src_scan += 4;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ FX_BYTE dest_scan_o[3];
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int index = 2 - color;
+ if (blend_type) {
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, dest_scan[index], *src_scan);
+ blended = FXDIB_ALPHA_MERGE(*src_scan, blended, back_alpha);
+ dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
+ } else {
+ dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], *src_scan, alpha_ratio);
+ }
+ src_scan ++;
+ }
+ dest_scan += 4;
+ src_scan++;
+ }
+}
+void _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int src_gap = src_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ if (src_Bpp == 4) {
+ FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
+ } else {
+ FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
+ }
+ dest_scan += 4;
+ src_scan += src_Bpp;
+ continue;
+ }
+ dest_scan[3] = 0xff;
+ if (bNonseparableBlend) {
+ FX_BYTE dest_scan_o[3];
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int index = 2 - color;
+ int src_color = FX_GAMMA(*src_scan);
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, dest_scan[index], src_color);
+ dest_scan[index] = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
+ src_scan ++;
+ }
+ dest_scan += 4;
+ src_scan += src_gap;
+ }
+}
+inline void _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, FX_LPCBYTE clip_scan)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE src_alpha;
+ if (clip_scan) {
+ src_alpha = src_scan[3] * (*clip_scan++) / 255;
+ } else {
+ src_alpha = src_scan[3];
+ }
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_scan += 4;
+ continue;
+ }
+ if (bNonseparableBlend) {
+ FX_BYTE dest_scan_o[3];
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int index = 2 - color;
+ int back_color = FX_GAMMA(dest_scan[index]);
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, back_color, *src_scan);
+ dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
+ src_scan ++;
+ }
+ dest_scan += dest_Bpp;
+ src_scan ++;
+ }
+}
+inline void _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp)
+{
+ int src_gap = src_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ if (src_Bpp == 4) {
+ FXARGB_SETRGBORDERDIB(dest_scan, 0xff000000 | FXARGB_GETDIB(src_scan));
+ } else {
+ FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[2], src_scan[1], src_scan[0]));
+ }
+ dest_scan += 4;
+ src_scan += src_Bpp;
+ }
+}
+inline void _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int src_gap = src_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ if (bNonseparableBlend) {
+ FX_BYTE dest_scan_o[3];
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int index = 2 - color;
+ int back_color = FX_GAMMA(dest_scan[index]);
+ int src_color = FX_GAMMA(*src_scan);
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, back_color, src_color);
+ dest_scan[index] = FX_GAMMA_INVERSE(blended);
+ src_scan ++;
+ }
+ dest_scan += dest_Bpp;
+ src_scan += src_gap;
+ }
+}
+inline void _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE src_alpha;
+ if (clip_scan) {
+ src_alpha = src_scan[3] * (*clip_scan++) / 255;
+ } else {
+ src_alpha = src_scan[3];
+ }
+ if (src_alpha == 255) {
+ dest_scan[2] = FX_GAMMA_INVERSE(*src_scan++);
+ dest_scan[1] = FX_GAMMA_INVERSE(*src_scan++);
+ dest_scan[0] = FX_GAMMA_INVERSE(*src_scan++);
+ dest_scan += dest_Bpp;
+ src_scan ++;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_scan += 4;
+ continue;
+ }
+ for (int color = 0; color < 3; color ++) {
+ int index = 2 - color;
+ dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[index]), *src_scan, src_alpha));
+ src_scan ++;
+ }
+ dest_scan += dest_Bpp;
+ src_scan ++;
+ }
+}
+inline void _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp)
+{
+ for (int col = 0; col < width; col ++) {
+ dest_scan[2] = src_scan[0];
+ dest_scan[1] = src_scan[1];
+ dest_scan[0] = src_scan[2];
+ dest_scan += dest_Bpp;
+ src_scan += src_Bpp;
+ }
+}
+inline void _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int src_Bpp, FX_LPCBYTE clip_scan)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int src_gap = src_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ int src_alpha = *clip_scan ++;
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ dest_scan[2] = FX_GAMMA(*src_scan++);
+ dest_scan[1] = FX_GAMMA(*src_scan++);
+ dest_scan[0] = FX_GAMMA(*src_scan++);
+ src_scan += src_gap;
+ dest_scan += 4;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ src_scan += src_Bpp;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (bNonseparableBlend) {
+ FX_BYTE dest_scan_o[3];
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int index = 2 - color;
+ int src_color = FX_GAMMA(*src_scan);
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, dest_scan[index], src_color);
+ blended = FXDIB_ALPHA_MERGE(src_color, blended, back_alpha);
+ dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], blended, alpha_ratio);
+ src_scan ++;
+ }
+ dest_scan += 4;
+ src_scan += src_gap;
+ }
+}
+inline void _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int blend_type, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
+{
+ int blended_colors[3];
+ FX_BOOL bNonseparableBlend = blend_type >= FXDIB_BLEND_NONSEPARABLE;
+ int src_gap = src_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE src_alpha = *clip_scan ++;
+ if (src_alpha == 0) {
+ dest_scan += dest_Bpp;
+ src_scan += src_Bpp;
+ continue;
+ }
+ if (bNonseparableBlend) {
+ FX_BYTE dest_scan_o[3];
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ }
+ for (int color = 0; color < 3; color ++) {
+ int index = 2 - color;
+ int src_color = FX_GAMMA(*src_scan);
+ int back_color = FX_GAMMA(dest_scan[index]);
+ int blended = bNonseparableBlend ? blended_colors[color] :
+ _BLEND(blend_type, back_color, src_color);
+ dest_scan[index] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
+ src_scan ++;
+ }
+ dest_scan += dest_Bpp;
+ src_scan += src_gap;
+ }
+}
+inline void _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int src_Bpp, FX_LPCBYTE clip_scan)
+{
+ int src_gap = src_Bpp - 3;
+ for (int col = 0; col < width; col ++) {
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 255) {
+ dest_scan[2] = FX_GAMMA(*src_scan++);
+ dest_scan[1] = FX_GAMMA(*src_scan++);
+ dest_scan[0] = FX_GAMMA(*src_scan++);
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += src_gap;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ src_scan += src_Bpp;
+ continue;
+ }
+ int back_alpha = dest_scan[3];
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ for (int color = 0; color < 3; color ++) {
+ int index = 2 - color;
+ dest_scan[index] = FXDIB_ALPHA_MERGE(dest_scan[index], FX_GAMMA(*src_scan), alpha_ratio);
+ src_scan ++;
+ }
+ dest_scan += 4;
+ src_scan += src_gap;
+ }
+}
+inline void _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, int dest_Bpp, int src_Bpp, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < width; col ++) {
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 255) {
+ dest_scan[2] = src_scan[0];
+ dest_scan[1] = src_scan[1];
+ dest_scan[0] = src_scan[2];
+ } else if (src_alpha) {
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), FX_GAMMA(*src_scan), src_alpha));
+ src_scan ++;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), FX_GAMMA(*src_scan), src_alpha));
+ src_scan ++;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), FX_GAMMA(*src_scan), src_alpha));
+ dest_scan += dest_Bpp;
+ src_scan += src_Bpp - 2;
+ continue;
+ }
+ dest_scan += dest_Bpp;
+ src_scan += src_Bpp;
+ }
+}
+inline void _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, FX_ARGB* pPalette, int pixel_count,
+ int DestBpp, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ FX_ARGB argb = pPalette ? pPalette[*src_scan] : (*src_scan) * 0x010101;
+ int src_r = FXARGB_R(argb);
+ int src_g = FXARGB_G(argb);
+ int src_b = FXARGB_B(argb);
+ if (clip_scan && clip_scan[col] < 255) {
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
+ } else {
+ dest_scan[2] = src_b;
+ dest_scan[1] = src_g;
+ dest_scan[0] = src_r;
+ }
+ dest_scan += DestBpp;
+ src_scan ++;
+ }
+}
+inline void _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left,
+ FX_ARGB* pPalette, int pixel_count, int DestBpp, FX_LPCBYTE clip_scan)
+{
+ int reset_r, reset_g, reset_b;
+ int set_r, set_g, set_b;
+ if (pPalette) {
+ reset_r = FXARGB_R(pPalette[0]);
+ reset_g = FXARGB_G(pPalette[0]);
+ reset_b = FXARGB_B(pPalette[0]);
+ set_r = FXARGB_R(pPalette[1]);
+ set_g = FXARGB_G(pPalette[1]);
+ set_b = FXARGB_B(pPalette[1]);
+ } else {
+ reset_r = reset_g = reset_b = 0;
+ set_r = set_g = set_b = 255;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_r, src_g, src_b;
+ if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
+ src_r = set_r;
+ src_g = set_g;
+ src_b = set_b;
+ } else {
+ src_r = reset_r;
+ src_g = reset_g;
+ src_b = reset_b;
+ }
+ if (clip_scan && clip_scan[col] < 255) {
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, clip_scan[col]);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, clip_scan[col]);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, clip_scan[col]);
+ } else {
+ dest_scan[2] = src_b;
+ dest_scan[1] = src_g;
+ dest_scan[0] = src_r;
+ }
+ dest_scan += DestBpp;
+ }
+}
+inline void _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width,
+ FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < width; col ++) {
+ int src_r, src_g, src_b;
+ if (pPalette) {
+ FX_ARGB argb = pPalette[*src_scan];
+ src_r = FXARGB_R(argb);
+ src_g = FXARGB_G(argb);
+ src_b = FXARGB_B(argb);
+ } else {
+ src_r = src_g = src_b = *src_scan;
+ }
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ dest_scan[2] = FX_GAMMA(src_b);
+ dest_scan[1] = FX_GAMMA(src_g);
+ dest_scan[0] = FX_GAMMA(src_r);
+ dest_scan[3] = 255;
+ src_scan ++;
+ dest_scan += 4;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ src_scan ++;
+ continue;
+ }
+ int back_alpha = dest_scan[3];
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
+ dest_scan += 4;
+ src_scan ++;
+ }
+}
+inline void _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width,
+ FX_ARGB* pPalette, FX_LPCBYTE clip_scan)
+{
+ int reset_r, reset_g, reset_b;
+ int set_r, set_g, set_b;
+ if (pPalette) {
+ reset_r = FXARGB_R(pPalette[0]);
+ reset_g = FXARGB_G(pPalette[0]);
+ reset_b = FXARGB_B(pPalette[0]);
+ set_r = FXARGB_R(pPalette[1]);
+ set_g = FXARGB_G(pPalette[1]);
+ set_b = FXARGB_B(pPalette[1]);
+ } else {
+ reset_r = reset_g = reset_b = 0;
+ set_r = set_g = set_b = 255;
+ }
+ for (int col = 0; col < width; col ++) {
+ int src_r, src_g, src_b;
+ if (src_scan[(col + src_left) / 8] & (1 << (7 - (col + src_left) % 8))) {
+ src_r = set_r;
+ src_g = set_g;
+ src_b = set_b;
+ } else {
+ src_r = reset_r;
+ src_g = reset_g;
+ src_b = reset_b;
+ }
+ if (clip_scan == NULL || clip_scan[col] == 255) {
+ dest_scan[2] = FX_GAMMA(src_b);
+ dest_scan[1] = FX_GAMMA(src_g);
+ dest_scan[0] = FX_GAMMA(src_r);
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ continue;
+ }
+ int src_alpha = clip_scan[col];
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ continue;
+ }
+ int back_alpha = dest_scan[3];
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], FX_GAMMA(src_b), alpha_ratio);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], FX_GAMMA(src_g), alpha_ratio);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], FX_GAMMA(src_r), alpha_ratio);
+ dest_scan += 4;
+ }
+}
+void _CompositeRow_ByteMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
+ int blend_type, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
+ } else {
+ src_alpha = mask_alpha * src_scan[col] / 255;
+ }
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
+ dest_scan += 4;
+ continue;
+ }
+ if (src_alpha == 0) {
+ dest_scan += 4;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ FX_BYTE dest_scan_o[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
+ } else if (blend_type) {
+ int blended = _BLEND(blend_type, dest_scan[2], src_b);
+ blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
+ blended = _BLEND(blend_type, dest_scan[1], src_g);
+ blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
+ blended = _BLEND(blend_type, dest_scan[0], src_r);
+ blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
+ } else {
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
+ }
+ dest_scan += 4;
+ }
+}
+void _CompositeRow_ByteMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b, int pixel_count,
+ int blend_type, int Bpp, FX_LPCBYTE clip_scan)
+{
+ for (int col = 0; col < pixel_count; col ++) {
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] * src_scan[col] / 255 / 255;
+ } else {
+ src_alpha = mask_alpha * src_scan[col] / 255;
+ }
+ if (src_alpha == 0) {
+ dest_scan += Bpp;
+ continue;
+ }
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ FX_BYTE dest_scan_o[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
+ } else if (blend_type) {
+ int blended = _BLEND(blend_type, dest_scan[2], src_b);
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, src_alpha);
+ blended = _BLEND(blend_type, dest_scan[1], src_g);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, src_alpha);
+ blended = _BLEND(blend_type, dest_scan[0], src_r);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, src_alpha);
+ } else {
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, src_alpha);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, src_alpha);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, src_alpha);
+ }
+ dest_scan += Bpp;
+ }
+}
+void _CompositeRow_BitMask2Argb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
+ int src_left, int pixel_count, int blend_type, FX_LPCBYTE clip_scan)
+{
+ if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
+ FX_ARGB argb = FXARGB_MAKE(0xff, src_r, src_g, src_b);
+ for (int col = 0; col < pixel_count; col ++) {
+ if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
+ FXARGB_SETRGBORDERDIB(dest_scan, argb);
+ }
+ dest_scan += 4;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
+ dest_scan += 4;
+ continue;
+ }
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] / 255;
+ } else {
+ src_alpha = mask_alpha;
+ }
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETRGBORDERDIB(dest_scan, FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
+ dest_scan += 4;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ FX_BYTE dest_scan_o[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], alpha_ratio);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], alpha_ratio);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], alpha_ratio);
+ } else if (blend_type) {
+ int blended = _BLEND(blend_type, dest_scan[2], src_b);
+ blended = FXDIB_ALPHA_MERGE(src_b, blended, back_alpha);
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended, alpha_ratio);
+ blended = _BLEND(blend_type, dest_scan[1], src_g);
+ blended = FXDIB_ALPHA_MERGE(src_g, blended, back_alpha);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended, alpha_ratio);
+ blended = _BLEND(blend_type, dest_scan[0], src_r);
+ blended = FXDIB_ALPHA_MERGE(src_r, blended, back_alpha);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended, alpha_ratio);
+ } else {
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], src_b, alpha_ratio);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], src_g, alpha_ratio);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], src_r, alpha_ratio);
+ }
+ dest_scan += 4;
+ }
+}
+void _CompositeRow_BitMask2Rgb_RgbByteOrder(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int mask_alpha, int src_r, int src_g, int src_b,
+ int src_left, int pixel_count, int blend_type, int Bpp, FX_LPCBYTE clip_scan)
+{
+ if (blend_type == FXDIB_BLEND_NORMAL && clip_scan == NULL && mask_alpha == 255) {
+ for (int col = 0; col < pixel_count; col ++) {
+ if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
+ dest_scan[2] = src_b;
+ dest_scan[1] = src_g;
+ dest_scan[0] = src_r;
+ }
+ dest_scan += Bpp;
+ }
+ return;
+ }
+ for (int col = 0; col < pixel_count; col ++) {
+ if (!(src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8)))) {
+ dest_scan += Bpp;
+ continue;
+ }
+ int src_alpha;
+ if (clip_scan) {
+ src_alpha = mask_alpha * clip_scan[col] / 255;
+ } else {
+ src_alpha = mask_alpha;
+ }
+ if (src_alpha == 0) {
+ dest_scan += Bpp;
+ continue;
+ }
+ if (blend_type >= FXDIB_BLEND_NONSEPARABLE) {
+ int blended_colors[3];
+ FX_BYTE src_scan[3];
+ FX_BYTE dest_scan_o[3];
+ src_scan[0] = src_b;
+ src_scan[1] = src_g;
+ src_scan[2] = src_r;
+ dest_scan_o[0] = dest_scan[2];
+ dest_scan_o[1] = dest_scan[1];
+ dest_scan_o[2] = dest_scan[0];
+ _RGB_Blend(blend_type, src_scan, dest_scan_o, blended_colors);
+ dest_scan[2] = FXDIB_ALPHA_MERGE(dest_scan[2], blended_colors[0], src_alpha);
+ dest_scan[1] = FXDIB_ALPHA_MERGE(dest_scan[1], blended_colors[1], src_alpha);
+ dest_scan[0] = FXDIB_ALPHA_MERGE(dest_scan[0], blended_colors[2], src_alpha);
+ } else if (blend_type) {
+ int back_color = FX_GAMMA(dest_scan[2]);
+ int blended = _BLEND(blend_type, back_color, src_b);
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
+ back_color = FX_GAMMA(dest_scan[1]);
+ blended = _BLEND(blend_type, back_color, src_g);
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
+ back_color = FX_GAMMA(dest_scan[0]);
+ blended = _BLEND(blend_type, back_color, src_r);
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(back_color, blended, src_alpha));
+ } else {
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), src_b, src_alpha));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), src_g, src_alpha));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), src_r, src_alpha));
+ }
+ dest_scan += Bpp;
+ }
+}
+inline FX_BOOL _ScanlineCompositor_InitSourceMask(FXDIB_Format dest_format, int alpha_flag, FX_DWORD mask_color, int& mask_alpha,
+ int& mask_red, int& mask_green, int& mask_blue, int& mask_black,
+ void* icc_module, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
+ if (alpha_flag >> 8) {
+ mask_alpha = alpha_flag & 0xff;
+ mask_red = FXSYS_GetCValue(mask_color);
+ mask_green = FXSYS_GetMValue(mask_color);
+ mask_blue = FXSYS_GetYValue(mask_color);
+ mask_black = FXSYS_GetKValue(mask_color);
+ } else {
+ mask_alpha = FXARGB_A(mask_color);
+ mask_red = FXARGB_R(mask_color);
+ mask_green = FXARGB_G(mask_color);
+ mask_blue = FXARGB_B(mask_color);
+ }
+ if (dest_format == FXDIB_8bppMask) {
+ return TRUE;
+ }
+ if ((dest_format & 0xff) == 8) {
+ if (pIccTransform) {
+ mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
+ FX_LPBYTE gray_p = (FX_LPBYTE)&mask_color;
+ pIccModule->TranslateScanline(pIccTransform, gray_p, gray_p, 1);
+ mask_red = dest_format & 0x0400 ? FX_CCOLOR(gray_p[0]) : gray_p[0];
+ } else {
+ if (alpha_flag >> 8) {
+ FX_BYTE r, g, b;
+ AdobeCMYK_to_sRGB1(mask_red, mask_green, mask_blue, mask_black,
+ r, g, b);
+ mask_red = FXRGB2GRAY(r, g, b);
+ } else {
+ mask_red = FXRGB2GRAY(mask_red, mask_green, mask_blue);
+ }
+ if (dest_format & 0x0400) {
+ mask_red = FX_CCOLOR(mask_red);
+ }
+ }
+ } else {
+ FX_LPBYTE mask_color_p = (FX_LPBYTE)&mask_color;
+ mask_color = (alpha_flag >> 8) ? FXCMYK_TODIB(mask_color) : FXARGB_TODIB(mask_color);
+ if (pIccTransform) {
+ pIccModule->TranslateScanline(pIccTransform, mask_color_p, mask_color_p, 1);
+ mask_red = mask_color_p[2];
+ mask_green = mask_color_p[1];
+ mask_blue = mask_color_p[0];
+ } else if (alpha_flag >> 8) {
+ AdobeCMYK_to_sRGB1(mask_color_p[0], mask_color_p[1], mask_color_p[2], mask_color_p[3],
+ mask_color_p[2], mask_color_p[1], mask_color_p[0]);
+ mask_red = mask_color_p[2];
+ mask_green = mask_color_p[1];
+ mask_blue = mask_color_p[0];
+ }
+ }
+ return TRUE;
+}
+inline void _ScanlineCompositor_InitSourcePalette(FXDIB_Format src_format, FXDIB_Format dest_format,
+ FX_DWORD*& pDestPalette, FX_DWORD* pSrcPalette,
+ void* icc_module, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = (ICodec_IccModule*)icc_module;
+ FX_BOOL isSrcCmyk = src_format & 0x0400 ? TRUE : FALSE;
+ FX_BOOL isDstCmyk = dest_format & 0x0400 ? TRUE : FALSE;
+ pDestPalette = NULL;
+ if (pIccTransform) {
+ if (pSrcPalette) {
+ if ((dest_format & 0xff) == 8) {
+ int pal_count = 1 << (src_format & 0xff);
+ FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
+ if (!gray_pal) {
+ return;
+ }
+ pDestPalette = (FX_DWORD*)gray_pal;
+ for (int i = 0; i < pal_count; i ++) {
+ FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
+ pIccModule->TranslateScanline(pIccTransform, gray_pal, (FX_LPCBYTE)&color, 1);
+ gray_pal ++;
+ }
+ } else {
+ int palsize = 1 << (src_format & 0xff);
+ pDestPalette = FX_Alloc(FX_DWORD, palsize);
+ if (!pDestPalette) {
+ return;
+ }
+ for (int i = 0; i < palsize; i ++) {
+ FX_DWORD color = isSrcCmyk ? FXCMYK_TODIB(pSrcPalette[i]) : FXARGB_TODIB(pSrcPalette[i]);
+ pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&color, (FX_LPCBYTE)&color, 1);
+ pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
+ }
+ }
+ } else {
+ int pal_count = 1 << (src_format & 0xff);
+ FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
+ if (!gray_pal) {
+ return;
+ }
+ if (pal_count == 2) {
+ gray_pal[0] = 0;
+ gray_pal[1] = 255;
+ } else {
+ for (int i = 0; i < pal_count; i++) {
+ gray_pal[i] = i;
+ }
+ }
+ if ((dest_format & 0xff) == 8) {
+ pIccModule->TranslateScanline(pIccTransform, gray_pal, gray_pal, pal_count);
+ pDestPalette = (FX_DWORD*)gray_pal;
+ } else {
+ pDestPalette = FX_Alloc(FX_DWORD, pal_count);
+ if (!pDestPalette) {
+ FX_Free(gray_pal);
+ return;
+ }
+ for (int i = 0; i < pal_count; i ++) {
+ pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&pDestPalette[i], &gray_pal[i], 1);
+ pDestPalette[i] = isDstCmyk ? FXCMYK_TODIB(pDestPalette[i]) : FXARGB_TODIB(pDestPalette[i]);
+ }
+ FX_Free(gray_pal);
+ }
+ }
+ } else {
+ if (pSrcPalette) {
+ if ((dest_format & 0xff) == 8) {
+ int pal_count = 1 << (src_format & 0xff);
+ FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
+ if (!gray_pal) {
+ return;
+ }
+ pDestPalette = (FX_DWORD*)gray_pal;
+ if (isSrcCmyk) {
+ for (int i = 0; i < pal_count; i ++) {
+ FX_CMYK cmyk = pSrcPalette[i];
+ FX_BYTE r, g, b;
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
+ r, g, b);
+ *gray_pal ++ = FXRGB2GRAY(r, g, b);
+ }
+ } else
+ for (int i = 0; i < pal_count; i ++) {
+ FX_ARGB argb = pSrcPalette[i];
+ *gray_pal ++ = FXRGB2GRAY(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
+ }
+ } else {
+ int palsize = 1 << (src_format & 0xff);
+ pDestPalette = FX_Alloc(FX_DWORD, palsize);
+ if (!pDestPalette) {
+ return;
+ }
+ if (isDstCmyk == isSrcCmyk) {
+ FXSYS_memcpy32(pDestPalette, pSrcPalette, palsize * sizeof(FX_DWORD));
+ } else {
+ for (int i = 0; i < palsize; i ++) {
+ FX_CMYK cmyk = pSrcPalette[i];
+ FX_BYTE r, g, b;
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
+ r, g, b);
+ pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
+ }
+ }
+ }
+ } else {
+ if ((dest_format & 0xff) == 8) {
+ int pal_count = 1 << (src_format & 0xff);
+ FX_LPBYTE gray_pal = FX_Alloc(FX_BYTE, pal_count);
+ if (!gray_pal) {
+ return;
+ }
+ if (pal_count == 2) {
+ gray_pal[0] = 0;
+ gray_pal[1] = 255;
+ } else {
+ for (int i = 0; i < pal_count; i++) {
+ gray_pal[i] = i;
+ }
+ }
+ pDestPalette = (FX_DWORD*)gray_pal;
+ } else {
+ int palsize = 1 << (src_format & 0xff);
+ pDestPalette = FX_Alloc(FX_DWORD, palsize);
+ if (!pDestPalette) {
+ return;
+ }
+ if (palsize == 2) {
+ pDestPalette[0] = isSrcCmyk ? 255 : 0xff000000;
+ pDestPalette[1] = isSrcCmyk ? 0 : 0xffffffff;
+ } else {
+ for (int i = 0; i < palsize; i++) {
+ pDestPalette[i] = isSrcCmyk ? FX_CCOLOR(i) : (i * 0x10101);
+ }
+ }
+ if (isSrcCmyk != isDstCmyk) {
+ for (int i = 0; i < palsize; i ++) {
+ FX_CMYK cmyk = pDestPalette[i];
+ FX_BYTE r, g, b;
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk), FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk),
+ r, g, b);
+ pDestPalette[i] = FXARGB_MAKE(0xff, r, g, b);
+ }
+ }
+ }
+ }
+ }
+}
+CFX_ScanlineCompositor::CFX_ScanlineCompositor()
+{
+ m_pSrcPalette = NULL;
+ m_pCacheScanline = NULL;
+ m_CacheSize = 0;
+ m_bRgbByteOrder = FALSE;
+ m_BlendType = FXDIB_BLEND_NORMAL;
+}
+CFX_ScanlineCompositor::~CFX_ScanlineCompositor()
+{
+ if (m_pSrcPalette) {
+ FX_Free(m_pSrcPalette);
+ }
+ if (m_pCacheScanline) {
+ FX_Free(m_pCacheScanline);
+ }
+}
+FX_BOOL CFX_ScanlineCompositor::Init(FXDIB_Format dest_format, FXDIB_Format src_format, FX_INT32 width, FX_DWORD* pSrcPalette,
+ FX_DWORD mask_color, int blend_type, FX_BOOL bClip, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
+{
+ m_SrcFormat = src_format;
+ m_DestFormat = dest_format;
+ m_BlendType = blend_type;
+ m_bRgbByteOrder = bRgbByteOrder;
+ ICodec_IccModule* pIccModule = NULL;
+ if (CFX_GEModule::Get()->GetCodecModule()) {
+ pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ }
+ if (pIccModule == NULL) {
+ pIccTransform = NULL;
+ }
+ m_pIccTransform = pIccTransform;
+ if ((dest_format & 0xff) == 1) {
+ return FALSE;
+ }
+ if (m_SrcFormat == FXDIB_1bppMask || m_SrcFormat == FXDIB_8bppMask) {
+ return _ScanlineCompositor_InitSourceMask(dest_format, alpha_flag, mask_color,
+ m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue, m_MaskBlack,
+ pIccModule, pIccTransform);
+ }
+ if (pIccTransform == NULL && (~src_format & 0x0400) && (dest_format & 0x0400)) {
+ return FALSE;
+ }
+ if ((m_SrcFormat & 0xff) <= 8) {
+ if (dest_format == FXDIB_8bppMask) {
+ return TRUE;
+ }
+ _ScanlineCompositor_InitSourcePalette(src_format, dest_format, m_pSrcPalette, pSrcPalette,
+ pIccModule, pIccTransform);
+ m_Transparency = (dest_format == FXDIB_Argb ? 1 : 0)
+ + (dest_format & 0x0200 ? 2 : 0)
+ + (dest_format & 0x0400 ? 4 : 0)
+ + ((src_format & 0xff) == 1 ? 8 : 0);
+ return TRUE;
+ }
+ m_Transparency = (src_format & 0x0200 ? 0 : 1)
+ + (dest_format & 0x0200 ? 0 : 2)
+ + (blend_type == FXDIB_BLEND_NORMAL ? 4 : 0)
+ + (bClip ? 8 : 0)
+ + (src_format & 0x0400 ? 16 : 0)
+ + (dest_format & 0x0400 ? 32 : 0)
+ + (pIccTransform ? 64 : 0);
+ return TRUE;
+}
+void CFX_ScanlineCompositor::CompositeRgbBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
+{
+ int src_Bpp = (m_SrcFormat & 0xff) >> 3;
+ int dest_Bpp = (m_DestFormat & 0xff) >> 3;
+ int dest_Size = width * dest_Bpp + 4;
+ if (m_bRgbByteOrder) {
+ switch (m_Transparency) {
+ case 0:
+ case 4:
+ case 8:
+ case 12:
+ _CompositeRow_Argb2Argb_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, clip_scan);
+ break;
+ case 1:
+ _CompositeRow_Rgb2Argb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp);
+ break;
+ case 2:
+ case 10:
+ _CompositeRow_Argb2Rgb_Blend_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan);
+ break;
+ case 3:
+ _CompositeRow_Rgb2Rgb_Blend_NoClip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
+ break;
+ case 5:
+ _CompositeRow_Rgb2Argb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp);
+ break;
+ case 6:
+ case 14:
+ _CompositeRow_Argb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, clip_scan);
+ break;
+ case 7:
+ _CompositeRow_Rgb2Rgb_NoBlend_NoClip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
+ break;
+ case 9:
+ _CompositeRow_Rgb2Argb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan);
+ break;
+ case 11:
+ _CompositeRow_Rgb2Rgb_Blend_Clip_RgbByteOrder(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
+ break;
+ case 13:
+ _CompositeRow_Rgb2Argb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, src_Bpp, clip_scan);
+ break;
+ case 15:
+ _CompositeRow_Rgb2Rgb_NoBlend_Clip_RgbByteOrder(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
+ break;
+ }
+ return;
+ }
+ if (m_DestFormat == FXDIB_8bppMask) {
+ if (m_SrcFormat & 0x0200) {
+ if (m_SrcFormat == FXDIB_Argb) {
+ _CompositeRow_Argb2Mask(dest_scan, src_scan, width, clip_scan);
+ } else {
+ _CompositeRow_Rgba2Mask(dest_scan, src_extra_alpha, width, clip_scan);
+ }
+ } else {
+ _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
+ }
+ } else if ((m_DestFormat & 0xff) == 8) {
+ if (m_DestFormat & 0x0400) {
+ for (int i = 0; i < width; i ++) {
+ *dest_scan = ~*dest_scan;
+ dest_scan++;
+ }
+ }
+ if (m_SrcFormat & 0x0200) {
+ if (m_DestFormat & 0x0200) {
+ _CompositeRow_Argb2Graya(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, dst_extra_alpha, m_pIccTransform);
+ } else {
+ _CompositeRow_Argb2Gray(dest_scan, src_scan, width, m_BlendType, clip_scan, src_extra_alpha, m_pIccTransform);
+ }
+ } else {
+ if (m_DestFormat & 0x0200) {
+ _CompositeRow_Rgb2Graya(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, dst_extra_alpha, m_pIccTransform);
+ } else {
+ _CompositeRow_Rgb2Gray(dest_scan, src_scan, src_Bpp, width, m_BlendType, clip_scan, m_pIccTransform);
+ }
+ }
+ if (m_DestFormat & 0x0400) {
+ for (int i = 0; i < width; i ++) {
+ *dest_scan = ~*dest_scan;
+ dest_scan++;
+ }
+ }
+ } else {
+ if (dest_Size > m_CacheSize) {
+ m_pCacheScanline = FX_Realloc(FX_BYTE, m_pCacheScanline, dest_Size);
+ if (!m_pCacheScanline) {
+ return;
+ }
+ m_CacheSize = dest_Size;
+ }
+ switch (m_Transparency) {
+ case 0:
+ case 4:
+ case 8:
+ case 4+8: {
+ _CompositeRow_Argb2Argb(dest_scan, src_scan, width, m_BlendType, clip_scan,
+ dst_extra_alpha, src_extra_alpha);
+ }
+ break;
+ case 64:
+ case 4+64:
+ case 8+64:
+ case 4+8+64: {
+ _CompositeRow_Argb2Argb_Transform(dest_scan, src_scan, width, m_BlendType, clip_scan,
+ dst_extra_alpha, src_extra_alpha, m_pCacheScanline, m_pIccTransform);
+ }
+ break;
+ case 1:
+ _CompositeRow_Rgb2Argb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, src_Bpp,
+ dst_extra_alpha);
+ break;
+ case 1+64:
+ _CompositeRow_Rgb2Argb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp,
+ dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
+ break;
+ case 1+8:
+ _CompositeRow_Rgb2Argb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
+ dst_extra_alpha);
+ break;
+ case 1+8+64:
+ _CompositeRow_Rgb2Argb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, src_Bpp, clip_scan,
+ dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
+ break;
+ case 1+4:
+ _CompositeRow_Rgb2Argb_NoBlend_NoClip(dest_scan, src_scan, width, src_Bpp,
+ dst_extra_alpha);
+ break;
+ case 1+4+64:
+ _CompositeRow_Rgb2Argb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, src_Bpp,
+ dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
+ break;
+ case 1+4+8:
+ _CompositeRow_Rgb2Argb_NoBlend_Clip(dest_scan, src_scan, width, src_Bpp, clip_scan,
+ dst_extra_alpha);
+ break;
+ case 1+4+8+64:
+ _CompositeRow_Rgb2Argb_NoBlend_Clip_Transform(dest_scan, src_scan, width, src_Bpp, clip_scan,
+ dst_extra_alpha, m_pCacheScanline, m_pIccTransform);
+ break;
+ case 2:
+ case 2+8:
+ _CompositeRow_Argb2Rgb_Blend(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
+ src_extra_alpha);
+ break;
+ case 2+64:
+ case 2+8+64:
+ _CompositeRow_Argb2Rgb_Blend_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, clip_scan,
+ src_extra_alpha, m_pCacheScanline, m_pIccTransform);
+ break;
+ case 2+4:
+ case 2+4+8:
+ _CompositeRow_Argb2Rgb_NoBlend(dest_scan, src_scan, width, dest_Bpp, clip_scan,
+ src_extra_alpha);
+ break;
+ case 2+4+64:
+ case 2+4+8+64:
+ _CompositeRow_Argb2Rgb_NoBlend_Transform(dest_scan, src_scan, width, dest_Bpp, clip_scan,
+ src_extra_alpha, m_pCacheScanline, m_pIccTransform);
+ break;
+ case 1+2:
+ _CompositeRow_Rgb2Rgb_Blend_NoClip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp);
+ break;
+ case 1+2+64:
+ _CompositeRow_Rgb2Rgb_Blend_NoClip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp,
+ m_pCacheScanline, m_pIccTransform);
+ break;
+ case 1+2+8:
+ _CompositeRow_Rgb2Rgb_Blend_Clip(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan);
+ break;
+ case 1+2+8+64:
+ _CompositeRow_Rgb2Rgb_Blend_Clip_Transform(dest_scan, src_scan, width, m_BlendType, dest_Bpp, src_Bpp, clip_scan,
+ m_pCacheScanline, m_pIccTransform);
+ break;
+ case 1+2+4:
+ _CompositeRow_Rgb2Rgb_NoBlend_NoClip(dest_scan, src_scan, width, dest_Bpp, src_Bpp);
+ break;
+ case 1+2+4+64:
+ _CompositeRow_Rgb2Rgb_NoBlend_NoClip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp,
+ m_pCacheScanline, m_pIccTransform);
+ break;
+ case 1+2+4+8:
+ _CompositeRow_Rgb2Rgb_NoBlend_Clip(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan);
+ break;
+ case 1+2+4+8+64:
+ _CompositeRow_Rgb2Rgb_NoBlend_Clip_Transform(dest_scan, src_scan, width, dest_Bpp, src_Bpp, clip_scan,
+ m_pCacheScanline, m_pIccTransform);
+ break;
+ }
+ }
+}
+void CFX_ScanlineCompositor::CompositePalBitmapLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
+{
+ if (m_bRgbByteOrder) {
+ if (m_SrcFormat == FXDIB_1bppRgb) {
+ if (m_DestFormat == FXDIB_8bppRgb) {
+ return;
+ } else if(m_DestFormat == FXDIB_Argb) {
+ _CompositeRow_1bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
+ } else {
+ _CompositeRow_1bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
+ }
+ } else {
+ if (m_DestFormat == FXDIB_8bppRgb) {
+ return;
+ } else if (m_DestFormat == FXDIB_Argb) {
+ _CompositeRow_8bppRgb2Argb_NoBlend_RgbByteOrder(dest_scan, src_scan, width, m_pSrcPalette, clip_scan);
+ } else {
+ _CompositeRow_8bppRgb2Rgb_NoBlend_RgbByteOrder(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
+ }
+ }
+ return;
+ }
+ if (m_DestFormat == FXDIB_8bppMask) {
+ _CompositeRow_Rgb2Mask(dest_scan, src_scan, width, clip_scan);
+ return;
+ } else if ((m_DestFormat & 0xff) == 8) {
+ if (m_Transparency & 8) {
+ if (m_DestFormat & 0x0200) {
+ _CompositeRow_1bppPal2Graya(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan, dst_extra_alpha);
+ } else {
+ _CompositeRow_1bppPal2Gray(dest_scan, src_scan, src_left, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan);
+ }
+ } else {
+ if (m_DestFormat & 0x0200)
+ _CompositeRow_8bppPal2Graya(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
+ dst_extra_alpha, src_extra_alpha);
+ else
+ _CompositeRow_8bppPal2Gray(dest_scan, src_scan, (FX_LPCBYTE)m_pSrcPalette, width, m_BlendType, clip_scan,
+ src_extra_alpha);
+ }
+ } else {
+ switch (m_Transparency) {
+ case 1+2:
+ _CompositeRow_8bppRgb2Argb_NoBlend(dest_scan, src_scan, width, m_pSrcPalette, clip_scan,
+ src_extra_alpha);
+ break;
+ case 1+2+8:
+ _CompositeRow_1bppRgb2Argb_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan);
+ break;
+ case 0:
+ _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
+ src_extra_alpha);
+ break;
+ case 0+8:
+ _CompositeRow_1bppRgb2Rgb_NoBlend(dest_scan, src_scan, src_left, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan);
+ break;
+ case 0+2:
+ _CompositeRow_8bppRgb2Rgb_NoBlend(dest_scan, src_scan, m_pSrcPalette, width, (m_DestFormat & 0xff) >> 3, clip_scan,
+ src_extra_alpha);
+ break;
+ case 0+2+8:
+ _CompositeRow_1bppRgb2Rgba_NoBlend(dest_scan, src_scan, src_left, width, m_pSrcPalette, clip_scan,
+ dst_extra_alpha);
+ break;
+ break;
+ }
+ }
+}
+void CFX_ScanlineCompositor::CompositeByteMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int width, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dst_extra_alpha)
+{
+ if (m_DestFormat == FXDIB_8bppMask) {
+ _CompositeRow_ByteMask2Mask(dest_scan, src_scan, m_MaskAlpha, width, clip_scan);
+ } else if ((m_DestFormat & 0xff) == 8) {
+ if (m_DestFormat & 0x0200) {
+ _CompositeRow_ByteMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan, dst_extra_alpha);
+ } else {
+ _CompositeRow_ByteMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, width, clip_scan);
+ }
+ } else if (m_bRgbByteOrder) {
+ if (m_DestFormat == FXDIB_Argb)
+ _CompositeRow_ByteMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
+ width, m_BlendType, clip_scan);
+ else
+ _CompositeRow_ByteMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
+ width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
+ return;
+ } else if (m_DestFormat == FXDIB_Argb)
+ _CompositeRow_ByteMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
+ width, m_BlendType, clip_scan);
+ else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
+ _CompositeRow_ByteMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
+ width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
+ else if (m_DestFormat == FXDIB_Rgba)
+ _CompositeRow_ByteMask2Rgba(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
+ width, m_BlendType, clip_scan, dst_extra_alpha);
+}
+void CFX_ScanlineCompositor::CompositeBitMaskLine(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int src_left, int width, FX_LPCBYTE clip_scan,
+ FX_LPBYTE dst_extra_alpha)
+{
+ if (m_DestFormat == FXDIB_8bppMask) {
+ _CompositeRow_BitMask2Mask(dest_scan, src_scan, m_MaskAlpha, src_left, width, clip_scan);
+ } else if ((m_DestFormat & 0xff) == 8) {
+ if (m_DestFormat & 0x0200)
+ _CompositeRow_BitMask2Graya(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan,
+ dst_extra_alpha);
+ else {
+ _CompositeRow_BitMask2Gray(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, src_left, width, clip_scan);
+ }
+ } else if (m_bRgbByteOrder) {
+ if (m_DestFormat == FXDIB_Argb)
+ _CompositeRow_BitMask2Argb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
+ src_left, width, m_BlendType, clip_scan);
+ else
+ _CompositeRow_BitMask2Rgb_RgbByteOrder(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
+ src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
+ return;
+ } else if (m_DestFormat == FXDIB_Argb)
+ _CompositeRow_BitMask2Argb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
+ src_left, width, m_BlendType, clip_scan);
+ else if (m_DestFormat == FXDIB_Rgb || m_DestFormat == FXDIB_Rgb32)
+ _CompositeRow_BitMask2Rgb(dest_scan, src_scan, m_MaskAlpha, m_MaskRed, m_MaskGreen, m_MaskBlue,
+ src_left, width, m_BlendType, (m_DestFormat & 0xff) >> 3, clip_scan);
+}
+FX_BOOL CFX_DIBitmap::CompositeBitmap(int dest_left, int dest_top, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top,
+ int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, void* pIccTransform)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ ASSERT(!pSrcBitmap->IsAlphaMask());
+ ASSERT(m_bpp >= 8);
+ if (pSrcBitmap->IsAlphaMask() || m_bpp < 8) {
+ return FALSE;
+ }
+ GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(),
+ src_left, src_top, pClipRgn);
+ if (width == 0 || height == 0) {
+ return TRUE;
+ }
+ const CFX_DIBitmap* pClipMask = NULL;
+ FX_RECT clip_box;
+ if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
+ ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
+ pClipMask = pClipRgn->GetMask();
+ clip_box = pClipRgn->GetBox();
+ }
+ CFX_ScanlineCompositor compositor;
+ if (!compositor.Init(GetFormat(), pSrcBitmap->GetFormat(), width, pSrcBitmap->GetPalette(), 0, blend_type,
+ pClipMask != NULL, bRgbByteOrder, 0, pIccTransform)) {
+ return FALSE;
+ }
+ int dest_Bpp = m_bpp / 8;
+ int src_Bpp = pSrcBitmap->GetBPP() / 8;
+ FX_BOOL bRgb = FALSE;
+ FX_BOOL bCmyk = FALSE;
+ if (src_Bpp > 1) {
+ if (pSrcBitmap->IsCmykImage()) {
+ bCmyk = TRUE;
+ } else {
+ bRgb = TRUE;
+ }
+ }
+ CFX_DIBitmap* pSrcAlphaMask = pSrcBitmap->m_pAlphaMask;
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * dest_Bpp;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * src_Bpp;
+ FX_LPCBYTE src_scan_extra_alpha = pSrcAlphaMask ? pSrcAlphaMask->GetScanline(src_top + row) + src_left : NULL;
+ FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
+ FX_LPCBYTE clip_scan = NULL;
+ if (pClipMask) {
+ clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
+ }
+ if (bRgb) {
+ compositor.CompositeRgbBitmapLine(dest_scan, src_scan, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
+ } else {
+ compositor.CompositePalBitmapLine(dest_scan, src_scan, src_left, width, clip_scan, src_scan_extra_alpha, dst_scan_extra_alpha);
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DIBitmap::CompositeMask(int dest_left, int dest_top, int width, int height,
+ const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top,
+ int blend_type, const CFX_ClipRgn* pClipRgn, FX_BOOL bRgbByteOrder, int alpha_flag, void* pIccTransform)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ ASSERT(pMask->IsAlphaMask());
+ ASSERT(m_bpp >= 8);
+ if (!pMask->IsAlphaMask() || m_bpp < 8) {
+ return FALSE;
+ }
+ GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, pClipRgn);
+ if (width == 0 || height == 0) {
+ return TRUE;
+ }
+ int src_alpha = (FX_BYTE)(alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
+ if (src_alpha == 0) {
+ return TRUE;
+ }
+ const CFX_DIBitmap* pClipMask = NULL;
+ FX_RECT clip_box;
+ if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
+ ASSERT(pClipRgn->GetType() == CFX_ClipRgn::MaskF);
+ pClipMask = pClipRgn->GetMask();
+ clip_box = pClipRgn->GetBox();
+ }
+ int src_bpp = pMask->GetBPP();
+ int Bpp = GetBPP() / 8;
+ CFX_ScanlineCompositor compositor;
+ if (!compositor.Init(GetFormat(), pMask->GetFormat(), width, NULL, color, blend_type, pClipMask != NULL, bRgbByteOrder, alpha_flag, pIccTransform)) {
+ return FALSE;
+ }
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp;
+ FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row);
+ FX_LPBYTE dst_scan_extra_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left : NULL;
+ FX_LPCBYTE clip_scan = NULL;
+ if (pClipMask) {
+ clip_scan = pClipMask->m_pBuffer + (dest_top + row - clip_box.top) * pClipMask->m_Pitch + (dest_left - clip_box.left);
+ }
+ if (src_bpp == 1) {
+ compositor.CompositeBitMaskLine(dest_scan, src_scan, src_left, width, clip_scan, dst_scan_extra_alpha);
+ } else {
+ compositor.CompositeByteMaskLine(dest_scan, src_scan + src_left, width, clip_scan, dst_scan_extra_alpha);
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DIBitmap::CompositeRect(int left, int top, int width, int height, FX_DWORD color, int alpha_flag, void* pIccTransform)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ int src_alpha = (alpha_flag >> 8) ? (alpha_flag & 0xff) : FXARGB_A(color);
+ if (src_alpha == 0) {
+ return TRUE;
+ }
+ FX_RECT rect(left, top, left + width, top + height);
+ rect.Intersect(0, 0, m_Width, m_Height);
+ if (rect.IsEmpty()) {
+ return TRUE;
+ }
+ width = rect.Width();
+ FX_DWORD dst_color;
+ if (alpha_flag >> 8) {
+ dst_color = FXCMYK_TODIB(color);
+ } else {
+ dst_color = FXARGB_TODIB(color);
+ }
+ FX_LPBYTE color_p = (FX_LPBYTE)&dst_color;
+ if (m_bpp == 8) {
+ FX_BYTE gray = 255;
+ if (!IsAlphaMask()) {
+ if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ pIccModule->TranslateScanline(pIccTransform, &gray, color_p, 1);
+ } else {
+ if (alpha_flag >> 8) {
+ FX_BYTE r, g, b;
+ AdobeCMYK_to_sRGB1(color_p[0], color_p[1], color_p[2], color_p[3],
+ r, g, b);
+ gray = FXRGB2GRAY(r, g, b);
+ } else {
+ gray = (FX_BYTE)FXRGB2GRAY((int)color_p[2], color_p[1], color_p[0]);
+ }
+ }
+ if (IsCmykImage()) {
+ gray = ~gray;
+ }
+ }
+ for (int row = rect.top; row < rect.bottom; row ++) {
+ FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left;
+ if (src_alpha == 255) {
+ FXSYS_memset8(dest_scan, gray, width);
+ } else
+ for (int col = 0; col < width; col ++) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, src_alpha);
+ dest_scan ++;
+ }
+ }
+ return TRUE;
+ } else if (m_bpp == 1) {
+ ASSERT(!IsCmykImage() && (FX_BYTE)(alpha_flag >> 8) == 0);
+ int left_shift = rect.left % 8;
+ int right_shift = rect.right % 8;
+ int width = rect.right / 8 - rect.left / 8;
+ int index = 0;
+ if (m_pPalette == NULL) {
+ index = ((FX_BYTE)color == 0xff) ? 1 : 0;
+ } else {
+ for (int i = 0; i < 2; i ++)
+ if (m_pPalette[i] == color) {
+ index = i;
+ }
+ }
+ for (int row = rect.top; row < rect.bottom; row ++) {
+ FX_BYTE* dest_scan_top = (FX_BYTE*)GetScanline(row) + rect.left / 8;
+ FX_BYTE* dest_scan_top_r = (FX_BYTE*)GetScanline(row) + rect.right / 8;
+ FX_BYTE left_flag = *dest_scan_top & (255 << (8 - left_shift));
+ FX_BYTE right_flag = *dest_scan_top_r & (255 >> right_shift);
+ if (width) {
+ FXSYS_memset8(dest_scan_top + 1, index ? 255 : 0, width - 1);
+ if (!index) {
+ *dest_scan_top &= left_flag;
+ *dest_scan_top_r &= right_flag;
+ } else {
+ *dest_scan_top |= ~left_flag;
+ *dest_scan_top_r |= ~right_flag;
+ }
+ } else {
+ if (!index) {
+ *dest_scan_top &= left_flag | right_flag;
+ } else {
+ *dest_scan_top |= ~(left_flag | right_flag);
+ }
+ }
+ }
+ return TRUE;
+ }
+ ASSERT(m_bpp >= 24);
+ if (m_bpp < 24) {
+ return FALSE;
+ }
+ if (pIccTransform && CFX_GEModule::Get()->GetCodecModule()) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1);
+ } else {
+ if (alpha_flag >> 8 && !IsCmykImage())
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color),
+ color_p[2], color_p[1], color_p[0]);
+ else if (!(alpha_flag >> 8) && IsCmykImage()) {
+ return FALSE;
+ }
+ }
+ if(!IsCmykImage()) {
+ color_p[3] = (FX_BYTE)src_alpha;
+ }
+ int Bpp = m_bpp / 8;
+ FX_BOOL bAlpha = HasAlpha();
+ FX_BOOL bArgb = GetFormat() == FXDIB_Argb ? TRUE : FALSE;
+ if (src_alpha == 255) {
+ for (int row = rect.top; row < rect.bottom; row ++) {
+ FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
+ FX_LPBYTE dest_scan_alpha = m_pAlphaMask ? (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left : NULL;
+ if (dest_scan_alpha) {
+ FXSYS_memset8(dest_scan_alpha, 0xff, width);
+ }
+ if (Bpp == 4) {
+ FX_DWORD* scan = (FX_DWORD*)dest_scan;
+ for (int col = 0; col < width; col ++) {
+ *scan ++ = dst_color;
+ }
+ } else {
+ for (int col = 0; col < width; col ++) {
+ *dest_scan ++ = color_p[0];
+ *dest_scan ++ = color_p[1];
+ *dest_scan ++ = color_p[2];
+ }
+ }
+ }
+ return TRUE;
+ }
+ for (int row = rect.top; row < rect.bottom; row ++) {
+ FX_LPBYTE dest_scan = m_pBuffer + row * m_Pitch + rect.left * Bpp;
+ if (bAlpha) {
+ if (bArgb) {
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha, color_p[2], color_p[1], color_p[0]));
+ dest_scan += 4;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[0], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[1], alpha_ratio);
+ dest_scan ++;
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[2], alpha_ratio);
+ dest_scan ++;
+ *dest_scan++ = dest_alpha;
+ }
+ } else {
+ FX_LPBYTE dest_scan_alpha = (FX_LPBYTE)m_pAlphaMask->GetScanline(row) + rect.left;
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE back_alpha = *dest_scan_alpha;
+ if (back_alpha == 0) {
+ *dest_scan_alpha++ = src_alpha;
+ FXSYS_memcpy32(dest_scan, color_p, Bpp);
+ dest_scan += Bpp;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha - back_alpha * src_alpha / 255;
+ *dest_scan_alpha ++ = dest_alpha;
+ int alpha_ratio = src_alpha * 255 / dest_alpha;
+ for(int comps = 0; comps < Bpp; comps ++) {
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], alpha_ratio);
+ dest_scan ++;
+ }
+ }
+ }
+ } else {
+ for (int col = 0; col < width; col ++) {
+ for(int comps = 0; comps < Bpp; comps ++) {
+ if (comps == 3) {
+ *dest_scan ++ = 255;
+ continue;
+ }
+ *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, color_p[comps], src_alpha);
+ dest_scan ++;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+CFX_BitmapComposer::CFX_BitmapComposer()
+{
+ m_pScanlineV = NULL;
+ m_pScanlineAlphaV = NULL;
+ m_pClipScanV = NULL;
+ m_pAddClipScan = NULL;
+ m_bRgbByteOrder = FALSE;
+ m_BlendType = FXDIB_BLEND_NORMAL;
+}
+CFX_BitmapComposer::~CFX_BitmapComposer()
+{
+ if (m_pScanlineV) {
+ FX_Free(m_pScanlineV);
+ }
+ if (m_pScanlineAlphaV) {
+ FX_Free(m_pScanlineAlphaV);
+ }
+ if (m_pClipScanV) {
+ FX_Free(m_pClipScanV);
+ }
+ if (m_pAddClipScan) {
+ FX_Free(m_pAddClipScan);
+ }
+}
+void CFX_BitmapComposer::Compose(CFX_DIBitmap* pDest, const CFX_ClipRgn* pClipRgn, int bitmap_alpha,
+ FX_DWORD mask_color, FX_RECT& dest_rect, FX_BOOL bVertical,
+ FX_BOOL bFlipX, FX_BOOL bFlipY, FX_BOOL bRgbByteOrder,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ m_pBitmap = pDest;
+ m_pClipRgn = pClipRgn;
+ m_DestLeft = dest_rect.left;
+ m_DestTop = dest_rect.top;
+ m_DestWidth = dest_rect.Width();
+ m_DestHeight = dest_rect.Height();
+ m_BitmapAlpha = bitmap_alpha;
+ m_MaskColor = mask_color;
+ m_pClipMask = NULL;
+ if (pClipRgn && pClipRgn->GetType() != CFX_ClipRgn::RectI) {
+ m_pClipMask = pClipRgn->GetMask();
+ }
+ m_bVertical = bVertical;
+ m_bFlipX = bFlipX;
+ m_bFlipY = bFlipY;
+ m_AlphaFlag = alpha_flag;
+ m_pIccTransform = pIccTransform;
+ m_bRgbByteOrder = bRgbByteOrder;
+ m_BlendType = blend_type;
+}
+FX_BOOL CFX_BitmapComposer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette)
+{
+ m_SrcFormat = src_format;
+ if (!m_Compositor.Init(m_pBitmap->GetFormat(), src_format, width, pSrcPalette, m_MaskColor, FXDIB_BLEND_NORMAL,
+ m_pClipMask != NULL || (m_BitmapAlpha < 255), m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform)) {
+ return FALSE;
+ }
+ if (m_bVertical) {
+ m_pScanlineV = FX_Alloc(FX_BYTE, m_pBitmap->GetBPP() / 8 * width + 4);
+ if (!m_pScanlineV) {
+ return FALSE;
+ }
+ m_pClipScanV = FX_Alloc(FX_BYTE, m_pBitmap->GetHeight());
+ if (!m_pClipScanV) {
+ return FALSE;
+ }
+ if (m_pBitmap->m_pAlphaMask) {
+ m_pScanlineAlphaV = FX_Alloc(FX_BYTE, width + 4);
+ if (!m_pScanlineAlphaV) {
+ return FALSE;
+ }
+ }
+ }
+ if (m_BitmapAlpha < 255) {
+ m_pAddClipScan = FX_Alloc(FX_BYTE, m_bVertical ? m_pBitmap->GetHeight() : m_pBitmap->GetWidth());
+ if (!m_pAddClipScan) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+void CFX_BitmapComposer::DoCompose(FX_LPBYTE dest_scan, FX_LPCBYTE src_scan, int dest_width, FX_LPCBYTE clip_scan,
+ FX_LPCBYTE src_extra_alpha, FX_LPBYTE dst_extra_alpha)
+{
+ if (m_BitmapAlpha < 255) {
+ if (clip_scan) {
+ for (int i = 0; i < dest_width; i ++) {
+ m_pAddClipScan[i] = clip_scan[i] * m_BitmapAlpha / 255;
+ }
+ } else {
+ FXSYS_memset8(m_pAddClipScan, m_BitmapAlpha, dest_width);
+ }
+ clip_scan = m_pAddClipScan;
+ }
+ if (m_SrcFormat == FXDIB_8bppMask) {
+ m_Compositor.CompositeByteMaskLine(dest_scan, src_scan, dest_width, clip_scan, dst_extra_alpha);
+ } else if ((m_SrcFormat & 0xff) == 8) {
+ m_Compositor.CompositePalBitmapLine(dest_scan, src_scan, 0, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
+ } else {
+ m_Compositor.CompositeRgbBitmapLine(dest_scan, src_scan, dest_width, clip_scan, src_extra_alpha, dst_extra_alpha);
+ }
+}
+void CFX_BitmapComposer::ComposeScanline(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
+{
+ if (m_bVertical) {
+ ComposeScanlineV(line, scanline, scan_extra_alpha);
+ return;
+ }
+ FX_LPCBYTE clip_scan = NULL;
+ if (m_pClipMask)
+ clip_scan = m_pClipMask->GetBuffer() + (m_DestTop + line - m_pClipRgn->GetBox().top) *
+ m_pClipMask->GetPitch() + (m_DestLeft - m_pClipRgn->GetBox().left);
+ FX_LPBYTE dest_scan = (FX_LPBYTE)m_pBitmap->GetScanline(line + m_DestTop) +
+ m_DestLeft * m_pBitmap->GetBPP() / 8;
+ FX_LPBYTE dest_alpha_scan = m_pBitmap->m_pAlphaMask ?
+ (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(line + m_DestTop) + m_DestLeft : NULL;
+ DoCompose(dest_scan, scanline, m_DestWidth, clip_scan, scan_extra_alpha, dest_alpha_scan);
+}
+void CFX_BitmapComposer::ComposeScanlineV(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
+{
+ int i;
+ int Bpp = m_pBitmap->GetBPP() / 8;
+ int dest_pitch = m_pBitmap->GetPitch();
+ int dest_alpha_pitch = m_pBitmap->m_pAlphaMask ? m_pBitmap->m_pAlphaMask->GetPitch() : 0;
+ int dest_x = m_DestLeft + (m_bFlipX ? (m_DestWidth - line - 1) : line);
+ FX_LPBYTE dest_buf = m_pBitmap->GetBuffer() + dest_x * Bpp + m_DestTop * dest_pitch;
+ FX_LPBYTE dest_alpha_buf = m_pBitmap->m_pAlphaMask ?
+ m_pBitmap->m_pAlphaMask->GetBuffer() + dest_x + m_DestTop * dest_alpha_pitch : NULL;
+ if (m_bFlipY) {
+ dest_buf += dest_pitch * (m_DestHeight - 1);
+ dest_alpha_buf += dest_alpha_pitch * (m_DestHeight - 1);
+ }
+ int y_step = dest_pitch;
+ int y_alpha_step = dest_alpha_pitch;
+ if (m_bFlipY) {
+ y_step = -y_step;
+ y_alpha_step = -y_alpha_step;
+ }
+ FX_LPBYTE src_scan = m_pScanlineV;
+ FX_LPBYTE dest_scan = dest_buf;
+ for (i = 0; i < m_DestHeight; i ++) {
+ for (int j = 0; j < Bpp; j ++) {
+ *src_scan++ = dest_scan[j];
+ }
+ dest_scan += y_step;
+ }
+ FX_LPBYTE src_alpha_scan = m_pScanlineAlphaV;
+ FX_LPBYTE dest_alpha_scan = dest_alpha_buf;
+ if (dest_alpha_scan) {
+ for (i = 0; i < m_DestHeight; i ++) {
+ *src_alpha_scan++ = *dest_alpha_scan;
+ dest_alpha_scan += y_alpha_step;
+ }
+ }
+ FX_LPBYTE clip_scan = NULL;
+ if (m_pClipMask) {
+ clip_scan = m_pClipScanV;
+ int clip_pitch = m_pClipMask->GetPitch();
+ FX_LPCBYTE src_clip = m_pClipMask->GetBuffer() + (m_DestTop - m_pClipRgn->GetBox().top) *
+ clip_pitch + (dest_x - m_pClipRgn->GetBox().left);
+ if (m_bFlipY) {
+ src_clip += clip_pitch * (m_DestHeight - 1);
+ clip_pitch = -clip_pitch;
+ }
+ for (i = 0; i < m_DestHeight; i ++) {
+ clip_scan[i] = *src_clip;
+ src_clip += clip_pitch;
+ }
+ }
+ DoCompose(m_pScanlineV, scanline, m_DestHeight, clip_scan, scan_extra_alpha, m_pScanlineAlphaV);
+ src_scan = m_pScanlineV;
+ dest_scan = dest_buf;
+ for (i = 0; i < m_DestHeight; i ++) {
+ for (int j = 0; j < Bpp; j ++) {
+ dest_scan[j] = *src_scan++;
+ }
+ dest_scan += y_step;
+ }
+ src_alpha_scan = m_pScanlineAlphaV;
+ dest_alpha_scan = dest_alpha_buf;
+ if (dest_alpha_scan) {
+ for (i = 0; i < m_DestHeight; i ++) {
+ *dest_alpha_scan = *src_alpha_scan++;
+ dest_alpha_scan += y_alpha_step;
+ }
+ }
+}
diff --git a/core/src/fxge/dib/fx_dib_convert.cpp b/core/src/fxge/dib/fx_dib_convert.cpp
index fe4a7bfd9a..0120721e35 100644
--- a/core/src/fxge/dib/fx_dib_convert.cpp
+++ b/core/src/fxge/dib/fx_dib_convert.cpp
@@ -1,1090 +1,1090 @@
-// 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 "../../../include/fxge/fx_dib.h"
-#include "../../../include/fxge/fx_ge.h"
-#include "../../../include/fxcodec/fx_codec.h"
-const FX_DWORD g_dwWinPalette[256] = {
- 0xff000000, 0xff800000, 0xff008000, 0xff808000, 0xff000080, 0xff800080,
- 0xff008080, 0xff808080, 0xffC0DCC0, 0xffA6CAF0, 0xff2A3FAA, 0xff2A3FFF,
- 0xff2A5F00, 0xff2A5F55, 0xff2A5FAA, 0xff2A5FFF, 0xff2A7F00, 0xff2A7F55,
- 0xff2A7FAA, 0xff2A7FFF, 0xff2A9F00, 0xff2A9F55, 0xff2A9FAA, 0xff2A9FFF,
- 0xff2ABF00, 0xff2ABF55, 0xff2ABFAA, 0xff2ABFFF, 0xff2ADF00, 0xff2ADF55,
- 0xff2ADFAA, 0xff2ADFFF, 0xff2AFF00, 0xff2AFF55, 0xff2AFFAA, 0xff2AFFFF,
- 0xff550000, 0xff550055, 0xff5500AA, 0xff5500FF, 0xff551F00, 0xff551F55,
- 0xff551FAA, 0xff551FFF, 0xff553F00, 0xff553F55, 0xff553FAA, 0xff553FFF,
- 0xff555F00, 0xff555F55, 0xff555FAA, 0xff555FFF, 0xff557F00, 0xff557F55,
- 0xff557FAA, 0xff557FFF, 0xff559F00, 0xff559F55, 0xff559FAA, 0xff559FFF,
- 0xff55BF00, 0xff55BF55, 0xff55BFAA, 0xff55BFFF, 0xff55DF00, 0xff55DF55,
- 0xff55DFAA, 0xff55DFFF, 0xff55FF00, 0xff55FF55, 0xff55FFAA, 0xff55FFFF,
- 0xff7F0000, 0xff7F0055, 0xff7F00AA, 0xff7F00FF, 0xff7F1F00, 0xff7F1F55,
- 0xff7F1FAA, 0xff7F1FFF, 0xff7F3F00, 0xff7F3F55, 0xff7F3FAA, 0xff7F3FFF,
- 0xff7F5F00, 0xff7F5F55, 0xff7F5FAA, 0xff7F5FFF, 0xff7F7F00, 0xff7F7F55,
- 0xff7F7FAA, 0xff7F7FFF, 0xff7F9F00, 0xff7F9F55, 0xff7F9FAA, 0xff7F9FFF,
- 0xff7FBF00, 0xff7FBF55, 0xff7FBFAA, 0xff7FBFFF, 0xff7FDF00, 0xff7FDF55,
- 0xff7FDFAA, 0xff7FDFFF, 0xff00FF7F, 0xff7FFF55, 0xff7FFFAA, 0xff7FFFFF,
- 0xffAA0000, 0xffAA0055, 0xffAA00AA, 0xffAA00FF, 0xffAA1F00, 0xffAA1F55,
- 0xffAA1FAA, 0xffAA1FFF, 0xffAA3F00, 0xffAA3F55, 0xffAA3FAA, 0xffAA3FFF,
- 0xffAA5F00, 0xffAA5F55, 0xffAA5FAA, 0xffAA5FFF, 0xffAA7F00, 0xffAA7F55,
- 0xffAA7FAA, 0xffAA7FFF, 0xffAA9F00, 0xffAA9F55, 0xffAA9FAA, 0xffAA9FFF,
- 0xffAABF00, 0xffAABF55, 0xffAABFAA, 0xffAABFFF, 0xffAADF00, 0xffAADF55,
- 0xffAADFAA, 0xffAADFFF, 0xffAAFF00, 0xffAAFF55, 0xffAAFFAA, 0xffAAFFFF,
- 0xffD40000, 0xffD40055, 0xffD400AA, 0xffD400FF, 0xffD41F00, 0xffD41F55,
- 0xffD41FAA, 0xffD41FFF, 0xffD43F00, 0xffD43F55, 0xffD43FAA, 0xffD43FFF,
- 0xffD45F00, 0xffD45F55, 0xffD45FAA, 0xffD45FFF, 0xffD47F00, 0xffD47F55,
- 0xffD47FAA, 0xffD4F7FF, 0xffD49F00, 0xffD49F55, 0xffD49FAA, 0xffD49FFF,
- 0xffD4BF00, 0xffD4BF55, 0xffD4BFAA, 0xffD4BFFF, 0xffD4DF00, 0xffD4DF55,
- 0xffD4DFAA, 0xffD4DFFF, 0xffD4FF00, 0xffD4FF55, 0xffD4FFAA, 0xffD4FFFF,
- 0xffFF0055, 0xffFF00AA, 0xffFF1F00, 0xffFF1F55, 0xffFF1FAA, 0xffFF1FFF,
- 0xffFF3F00, 0xffFF3F55, 0xffFF3FAA, 0xffFF3FFF, 0xffFF5F00, 0xffFF5F55,
- 0xffFF5FAA, 0xffFF5FFF, 0xffFF7F00, 0xffFF7F55, 0xffFF7FAA, 0xffFF7FFF,
- 0xffFF9F00, 0xffFF9F55, 0xffFF9FAA, 0xffFF9FFF, 0xffFFBF00, 0xffFFBF55,
- 0xffFFBFAA, 0xffFFBFFF, 0xffFFDF00, 0xffFFDF55, 0xffFFDFAA, 0xffFFDFFF,
- 0xffFFFF55, 0xffFFFFAA, 0xffCCCCFF, 0xffFFCCFF, 0xff33FFFF, 0xff66FFFF,
- 0xff99FFFF, 0xffCCFFFF, 0xff007F00, 0xff007F55, 0xff007FAA, 0xff007FFF,
- 0xff009F00, 0xff009F55, 0xff009FAA, 0xff009FFF, 0xff00BF00, 0xff00BF55,
- 0xff00BFAA, 0xff00BFFF, 0xff00DF00, 0xff00DF55, 0xff00DFAA, 0xff00DFFF,
- 0xff00FF55, 0xff00FFAA, 0xff2A0000, 0xff2A0055, 0xff2A00AA, 0xff2A00FF,
- 0xff2A1F00, 0xff2A1F55, 0xff2A1FAA, 0xff2A1FFF, 0xff2A3F00, 0xff2A3F55,
- 0xffFFFBF0, 0xffA0A0A4, 0xff808080, 0xffFF0000, 0xff00FF00, 0xffFF0000,
- 0xff0000FF, 0xffFF00FF, 0xff00FFFF, 0xffFFFFFF
-};
-const FX_DWORD g_dwMacPalette[256] = {
- 0xffFFFFFF, 0xffFFFFCC, 0xffFFFF99, 0xffFFFF66, 0xffFFFF33, 0xffFFFF00,
- 0xffFFCCFF, 0xffFFCCCC, 0xffFFCC99, 0xffFFCC66, 0xffFFCC33, 0xffFFCC00,
- 0xffFF99FF, 0xffFF99CC, 0xffFF9999, 0xffFF9966, 0xffFF9933, 0xffFF9900,
- 0xffFF66FF, 0xffFF66CC, 0xffFF6699, 0xffFF6666, 0xffFF6633, 0xffFF6600,
- 0xffFF33FF, 0xffFF33CC, 0xffFF3399, 0xffFF3366, 0xffFF3333, 0xffFF3300,
- 0xffFF00FF, 0xffFF00CC, 0xffFF0099, 0xffFF0066, 0xffFF0033, 0xffFF0000,
- 0xffCCFFFF, 0xffCCFFCC, 0xffCCFF99, 0xffCCFF66, 0xffCCFF33, 0xffCCFF00,
- 0xffCCCCFF, 0xffCCCCCC, 0xffCCCC99, 0xffCCCC66, 0xffCCCC33, 0xffCCCC00,
- 0xffCC99FF, 0xffCC99CC, 0xffCC9999, 0xffCC9966, 0xffCC9933, 0xffCC9900,
- 0xffCC66FF, 0xffCC66CC, 0xffCC6699, 0xffCC6666, 0xffCC6633, 0xffCC6600,
- 0xffCC33FF, 0xffCC33CC, 0xffCC3399, 0xffCC3366, 0xffCC3333, 0xffCC3300,
- 0xffCC00FF, 0xffCC00CC, 0xffCC0099, 0xffCC0066, 0xffCC0033, 0xffCC0000,
- 0xff99FFFF, 0xff99FFCC, 0xff99FF99, 0xff99FF66, 0xff99FF33, 0xff99FF00,
- 0xff99CCFF, 0xff99CCCC, 0xff99CC99, 0xff99CC66, 0xff99CC33, 0xff99CC00,
- 0xff9999FF, 0xff9999CC, 0xff999999, 0xff999966, 0xff999933, 0xff999900,
- 0xff9966FF, 0xff9966CC, 0xff996699, 0xff996666, 0xff996633, 0xff996600,
- 0xff9933FF, 0xff9933CC, 0xff993399, 0xff993366, 0xff993333, 0xff993300,
- 0xff9900FF, 0xff9900CC, 0xff990099, 0xff990066, 0xff990033, 0xff990000,
- 0xff66FFFF, 0xff66FFCC, 0xff66FF99, 0xff66FF66, 0xff66FF33, 0xff66FF00,
- 0xff66CCFF, 0xff66CCCC, 0xff66CC99, 0xff66CC66, 0xff66CC33, 0xff66CC00,
- 0xff6699FF, 0xff6699CC, 0xff669999, 0xff669966, 0xff669933, 0xff669900,
- 0xff6666FF, 0xff6666CC, 0xff666699, 0xff666666, 0xff666633, 0xff666600,
- 0xff6633FF, 0xff6633CC, 0xff663399, 0xff663366, 0xff663333, 0xff663300,
- 0xff6600FF, 0xff6600CC, 0xff660099, 0xff660066, 0xff660033, 0xff660000,
- 0xff33FFFF, 0xff33FFCC, 0xff33FF99, 0xff33FF66, 0xff33FF33, 0xff33FF00,
- 0xff33CCFF, 0xff33CCCC, 0xff33CC99, 0xff33CC66, 0xff33CC33, 0xff33CC00,
- 0xff3399FF, 0xff3399CC, 0xff339999, 0xff339966, 0xff339933, 0xff339900,
- 0xff3366FF, 0xff3366CC, 0xff336699, 0xff336666, 0xff336633, 0xff336600,
- 0xff3333FF, 0xff3333CC, 0xff333399, 0xff333366, 0xff333333, 0xff333300,
- 0xff3300FF, 0xff3300CC, 0xff330099, 0xff330066, 0xff330033, 0xff330000,
- 0xff00FFFF, 0xff00FFCC, 0xff00FF99, 0xff00FF66, 0xff00FF33, 0xff00FF00,
- 0xff00CCFF, 0xff00CCCC, 0xff00CC99, 0xff00CC66, 0xff00CC33, 0xff00CC00,
- 0xff0099FF, 0xff0099CC, 0xff009999, 0xff009966, 0xff009933, 0xff009900,
- 0xff0066FF, 0xff0066CC, 0xff006699, 0xff006666, 0xff006633, 0xff006600,
- 0xff0033FF, 0xff0033CC, 0xff003399, 0xff003366, 0xff003333, 0xff003300,
- 0xff0000FF, 0xff0000CC, 0xff000099, 0xff000066, 0xff000033,
- 0xffEE0000, 0xffDD0000, 0xffBB0000, 0xffAA0000, 0xff880000, 0xff770000,
- 0xff550000, 0xff440000, 0xff220000, 0xff110000, 0xff00EE00, 0xff00DD00,
- 0xff00BB00, 0xff00AA00, 0xff008800, 0xff007700, 0xff005500, 0xff004400,
- 0xff002200, 0xff001100, 0xff0000EE, 0xff0000DD, 0xff0000BB, 0xff0000AA,
- 0xff000088, 0xff000077, 0xff000055, 0xff000044, 0xff000022, 0xff000011,
- 0xffEEEEEE, 0xffDDDDDD, 0xffBBBBBB, 0xffAAAAAA, 0xff888888, 0xff777777,
- 0xff555555, 0xff444444, 0xff222222, 0xff111111, 0xff000000
-};
-class CFX_Palette : public CFX_Object
-{
-public:
- CFX_Palette();
- ~CFX_Palette();
-public:
- FX_BOOL BuildPalette(const CFX_DIBSource* pBitmap, int dwPaletteType);
- FX_DWORD* GetPalette() const
- {
- return m_pPalette;
- }
-
- FX_DWORD* GetColorLut()const
- {
- return m_cLut;
- }
- FX_DWORD* GetAmountLut()const
- {
- return m_aLut;
- }
- FX_INT32 Getlut()const
- {
- return m_lut;
- }
-protected:
- FX_DWORD* m_pPalette;
- FX_DWORD* m_cLut;
- FX_DWORD* m_aLut;
- int m_lut;
-};
-int _Partition(FX_DWORD* alut, FX_DWORD* clut, int l, int r)
-{
- FX_DWORD p_a = alut[l];
- FX_DWORD p_c = clut[l];
- while(l < r) {
- while(l < r && alut[r] >= p_a) {
- r--;
- }
- if (l < r) {
- alut[l] = alut[r];
- clut[l++] = clut[r];
- }
- while(l < r && alut[l] <= p_a) {
- l++;
- }
- if (l < r) {
- alut[r] = alut[l];
- clut[r--] = clut[l];
- }
- }
- alut[l] = p_a;
- clut[l] = p_c;
- return l;
-}
-void _Qsort(FX_DWORD* alut, FX_DWORD* clut, int l, int r)
-{
- if(l < r) {
- int pI = _Partition(alut, clut, l, r);
- _Qsort(alut, clut, l, pI - 1);
- _Qsort(alut, clut, pI + 1, r);
- }
-}
-void _ColorDecode(FX_DWORD pal_v, FX_BYTE& r, FX_BYTE& g, FX_BYTE& b)
-{
- r = (FX_BYTE)((pal_v & 0xf00) >> 4);
- g = (FX_BYTE)(pal_v & 0x0f0);
- b = (FX_BYTE)((pal_v & 0x00f) << 4);
-}
-void _Obtain_Pal(FX_DWORD* aLut, FX_DWORD*cLut, FX_DWORD* dest_pal, int pal_type, FX_DWORD* win_mac_pal, FX_DWORD lut)
-{
- int row, col;
- FX_DWORD lut_1 = lut - 1;
- if (pal_type == FXDIB_PALETTE_LOC) {
- for (row = 0; row < 256; row++) {
- int lut_offset = lut_1 - row;
- if (lut_offset < 0) {
- lut_offset += 256;
- }
- FX_DWORD color = cLut[lut_offset];
- FX_BYTE r, g, b;
- _ColorDecode(color, r, g, b);
- dest_pal[row] = ((FX_DWORD)r << 16) | ((FX_DWORD)g << 8) | b | 0xff000000;
- aLut[lut_offset] = row;
- }
- } else {
- for (row = 0; row < 256; row++) {
- int lut_offset = lut_1 - row;
- if (lut_offset < 0) {
- lut_offset += 256;
- }
- FX_BYTE r, g, b;
- _ColorDecode(cLut[lut_offset], r, g, b);
- int error, min_error = 1000000;
- int c_index = 0;
- for (col = 0; col < 256; col++) {
- FX_DWORD p_color = win_mac_pal[col];
- int d_r = r - (FX_BYTE)(p_color >> 16);
- int d_g = g - (FX_BYTE)(p_color >> 8);
- int d_b = b - (FX_BYTE)p_color;
- error = d_r * d_r + d_g * d_g + d_b * d_b;
- if (error < min_error) {
- min_error = error;
- c_index = col;
- }
- }
- dest_pal[row] = win_mac_pal[c_index];
- aLut[lut_offset] = row;
- }
- }
-}
-CFX_Palette::CFX_Palette()
-{
- m_pPalette = NULL;
- m_cLut = NULL;
- m_aLut = NULL;
- m_lut = 0;
-}
-CFX_Palette::~CFX_Palette()
-{
- if (m_pPalette) {
- FX_Free(m_pPalette);
- }
- if (m_cLut) {
- FX_Free(m_cLut);
- }
- if (m_aLut) {
- FX_Free(m_aLut);
- }
- m_lut = 0;
-}
-FX_BOOL CFX_Palette::BuildPalette(const CFX_DIBSource* pBitmap, int pal_type)
-{
- if (pBitmap == NULL) {
- return FALSE;
- }
- if (m_pPalette != NULL) {
- FX_Free(m_pPalette);
- }
- m_pPalette = FX_Alloc(FX_DWORD, 256);
- if (!m_pPalette) {
- return FALSE;
- }
- FXSYS_memset32(m_pPalette, 0, sizeof(FX_DWORD) * 256);
- int bpp = pBitmap->GetBPP() / 8;
- int width = pBitmap->GetWidth();
- int height = pBitmap->GetHeight();
- if (m_cLut) {
- FX_Free(m_cLut);
- m_cLut = NULL;
- }
- if (m_aLut) {
- FX_Free(m_aLut);
- m_aLut = NULL;
- }
- m_cLut = FX_Alloc(FX_DWORD, 4096);
- if (!m_cLut) {
- return FALSE;
- }
- m_aLut = FX_Alloc(FX_DWORD, 4096);
- if (!m_aLut) {
- return FALSE;
- }
- FXSYS_memset32(m_aLut, 0, sizeof(FX_DWORD) * 4096);
- FXSYS_memset32(m_cLut, 0, sizeof(FX_DWORD) * 4096);
- int row, col;
- m_lut = 0;
- for (row = 0; row < height; row++) {
- FX_BYTE* scan_line = (FX_BYTE*)pBitmap->GetScanline(row);
- for (col = 0; col < width; col++) {
- FX_BYTE* src_port = scan_line + col * bpp;
- FX_DWORD b = src_port[0] & 0xf0;
- FX_DWORD g = src_port[1] & 0xf0;
- FX_DWORD r = src_port[2] & 0xf0;
- FX_DWORD index = (r << 4) + g + (b >> 4);
- m_aLut[index]++;
- }
- }
- for (row = 0; row < 4096; row++) {
- if (m_aLut[row] != 0) {
- m_aLut[m_lut] = m_aLut[row];
- m_cLut[m_lut] = row;
- m_lut++;
- }
- }
- _Qsort(m_aLut, m_cLut, 0, m_lut - 1);
- FX_DWORD* win_mac_pal = NULL;
- if (pal_type == FXDIB_PALETTE_WIN) {
- win_mac_pal = (FX_DWORD*)g_dwWinPalette;
- } else if (pal_type == FXDIB_PALETTE_MAC) {
- win_mac_pal = (FX_DWORD*)g_dwMacPalette;
- }
- _Obtain_Pal(m_aLut, m_cLut, m_pPalette, pal_type, win_mac_pal, m_lut);
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_1bppMask2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
-{
- FX_BYTE set_gray, reset_gray;
- set_gray = 0xff;
- reset_gray = 0x00;
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FXSYS_memset8(dest_scan, reset_gray, width);
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
- for (int col = src_left; col < src_left + width; col ++) {
- if (src_scan[col / 8] & (1 << (7 - col % 8))) {
- *dest_scan = set_gray;
- }
- dest_scan ++;
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_8bppMask2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
-{
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
- FXSYS_memcpy32(dest_scan, src_scan, width);
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_1bppPlt2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- FX_DWORD* src_plt = pSrcBitmap->GetPalette();
- FX_BYTE gray[2];
- if (pIccTransform) {
- FX_DWORD plt[2];
- if (pSrcBitmap->IsCmykImage()) {
- plt[0] = FXCMYK_TODIB(src_plt[0]);
- plt[1] = FXCMYK_TODIB(src_plt[1]);
- } else {
- FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
- bgr_ptr[0] = FXARGB_B(src_plt[0]);
- bgr_ptr[1] = FXARGB_G(src_plt[0]);
- bgr_ptr[2] = FXARGB_R(src_plt[0]);
- bgr_ptr[3] = FXARGB_B(src_plt[1]);
- bgr_ptr[4] = FXARGB_G(src_plt[1]);
- bgr_ptr[5] = FXARGB_R(src_plt[1]);
- }
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- pIccModule->TranslateScanline(pIccTransform, gray, (FX_LPCBYTE)plt, 2);
- } else {
- FX_BYTE reset_r, reset_g, reset_b,
- set_r, set_g, set_b;
- if (pSrcBitmap->IsCmykImage()) {
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]),
- reset_r, reset_g, reset_b);
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1]),
- set_r, set_g, set_b);
- } else {
- reset_r = FXARGB_R(src_plt[0]);
- reset_g = FXARGB_G(src_plt[0]);
- reset_b = FXARGB_B(src_plt[0]);
- set_r = FXARGB_R(src_plt[1]);
- set_g = FXARGB_G(src_plt[1]);
- set_b = FXARGB_B(src_plt[1]);
- }
- gray[0] = FXRGB2GRAY(reset_r, reset_g, reset_b);
- gray[1] = FXRGB2GRAY(set_r, set_g, set_b);
- }
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FXSYS_memset8(dest_scan, gray[0], width);
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
- for (int col = src_left; col < src_left + width; col ++) {
- if (src_scan[col / 8] & (1 << (7 - col % 8))) {
- *dest_scan = gray[1];
- }
- dest_scan ++;
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_8bppPlt2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- FX_DWORD* src_plt = pSrcBitmap->GetPalette();
- FX_BYTE gray[256];
- if (pIccTransform) {
- FX_DWORD plt[256];
- if (pSrcBitmap->IsCmykImage()) {
- for (int i = 0; i < 256; i ++) {
- plt[i] = FXCMYK_TODIB(src_plt[i]);
- }
- } else {
- FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
- for (int i = 0; i < 256; i ++) {
- *bgr_ptr++ = FXARGB_B(src_plt[i]);
- *bgr_ptr++ = FXARGB_G(src_plt[i]);
- *bgr_ptr++ = FXARGB_R(src_plt[i]);
- }
- }
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- pIccModule->TranslateScanline(pIccTransform, gray, (FX_LPCBYTE)plt, 256);
- } else {
- if (pSrcBitmap->IsCmykImage()) {
- FX_BYTE r, g, b;
- for (int i = 0; i < 256; i ++) {
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]),
- r, g, b);
- gray[i] = FXRGB2GRAY(r, g, b);
- }
- } else
- for (int i = 0; i < 256; i ++) {
- gray[i] = FXRGB2GRAY(FXARGB_R(src_plt[i]), FXARGB_G(src_plt[i]), FXARGB_B(src_plt[i]));
- }
- }
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
- for (int col = 0; col < width; col ++) {
- *dest_scan++ = gray[*src_scan++];
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_RgbOrCmyk2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- int Bpp = pSrcBitmap->GetBPP() / 8;
- if (pIccTransform) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- if (Bpp == 3 || pSrcBitmap->IsCmykImage()) {
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, width);
- }
- } else {
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
- dest_scan++;
- src_scan += 4;
- }
- }
- }
- } else {
- if (pSrcBitmap->IsCmykImage()) {
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
- for (int col = 0; col < width; col ++) {
- FX_BYTE r, g, b;
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue((FX_DWORD)src_scan[0]), FXSYS_GetMValue((FX_DWORD)src_scan[1]), FXSYS_GetYValue((FX_DWORD)src_scan[2]), FXSYS_GetKValue((FX_DWORD)src_scan[3]),
- r, g, b);
- *dest_scan++ = FXRGB2GRAY(r, g, b);
- src_scan += 4;
- }
- }
- } else
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
- for (int col = 0; col < width; col ++) {
- *dest_scan++ = FXRGB2GRAY(src_scan[2], src_scan[1], src_scan[0]);
- src_scan += Bpp;
- }
- }
- }
- return TRUE;
-}
-inline void _ConvertBuffer_IndexCopy(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
-{
- if (pSrcBitmap->GetBPP() == 1) {
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FXSYS_memset32(dest_scan, 0, width);
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
- for (int col = src_left; col < src_left + width; col ++) {
- if (src_scan[col / 8] & (1 << (7 - col % 8))) {
- *dest_scan = 1;
- }
- dest_scan ++;
- }
- }
- } else {
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
- FXSYS_memcpy32(dest_scan, src_scan, width);
- }
- }
-}
-FX_BOOL _ConvertBuffer_Plt2PltRgb8(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt, void* pIccTransform)
-{
- _ConvertBuffer_IndexCopy(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
- FX_DWORD* src_plt = pSrcBitmap->GetPalette();
- int plt_size = pSrcBitmap->GetPaletteSize();
- if (pIccTransform) {
- FX_DWORD plt[256];
- FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
- if (pSrcBitmap->IsCmykImage()) {
- for (int i = 0; i < plt_size; i ++) {
- plt[i] = FXCMYK_TODIB(src_plt[i]);
- }
- } else {
- for (int i = 0; i < plt_size; i ++) {
- *bgr_ptr++ = FXARGB_B(src_plt[i]);
- *bgr_ptr++ = FXARGB_G(src_plt[i]);
- *bgr_ptr++ = FXARGB_R(src_plt[i]);
- }
- bgr_ptr = (FX_LPBYTE)plt;
- }
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)plt, (FX_LPCBYTE)plt, plt_size);
- for (int i = 0; i < plt_size; i ++) {
- dst_plt[i] = FXARGB_MAKE(0xff, bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]);
- bgr_ptr += 3;
- }
- } else {
- if (pSrcBitmap->IsCmykImage()) {
- for (int i = 0; i < plt_size; i ++) {
- FX_BYTE r, g, b;
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]),
- r, g, b);
- dst_plt[i] = FXARGB_MAKE(0xff, r, g, b);
- }
- } else {
- FXSYS_memcpy32(dst_plt, src_plt, plt_size * 4);
- }
- }
- return TRUE;
-}
-inline FX_BOOL _ConvertBuffer_Rgb2PltRgb8_NoTransform(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt)
-{
- int bpp = pSrcBitmap->GetBPP() / 8;
- int row, col;
- CFX_Palette palette;
- palette.BuildPalette(pSrcBitmap, FXDIB_PALETTE_LOC);
- FX_DWORD* cLut = palette.GetColorLut();
- FX_DWORD* aLut = palette.GetAmountLut();
- if (cLut == NULL || aLut == NULL) {
- return FALSE;
- }
- int lut = palette.Getlut();
- FX_DWORD* pPalette = palette.GetPalette();
- if (lut > 256) {
- int err, min_err;
- int lut_256 = lut - 256;
- for (row = 0; row < lut_256; row++) {
- min_err = 1000000;
- FX_BYTE r, g, b;
- _ColorDecode(cLut[row], r, g, b);
- int clrindex = 0;
- for (int col = 0; col < 256; col++) {
- FX_DWORD p_color = *(pPalette + col);
- int d_r = r - (FX_BYTE)(p_color >> 16);
- int d_g = g - (FX_BYTE)(p_color >> 8);
- int d_b = b - (FX_BYTE)(p_color);
- err = d_r * d_r + d_g * d_g + d_b * d_b;
- if (err < min_err) {
- min_err = err;
- clrindex = col;
- }
- }
- aLut[row] = clrindex;
- }
- }
- FX_INT32 lut_1 = lut - 1;
- for (row = 0; row < height; row ++) {
- FX_BYTE* src_scan = (FX_BYTE*)pSrcBitmap->GetScanline(src_top + row) + src_left;
- FX_BYTE* dest_scan = dest_buf + row * dest_pitch;
- for (col = 0; col < width; col++) {
- FX_BYTE* src_port = src_scan + col * bpp;
- int r = src_port[2] & 0xf0;
- int g = src_port[1] & 0xf0;
- int b = src_port[0] & 0xf0;
- FX_DWORD clrindex = (r << 4) + g + (b >> 4);
- for (int i = lut_1; i >= 0; i--)
- if (clrindex == cLut[i]) {
- *(dest_scan + col) = (FX_BYTE)(aLut[i]);
- break;
- }
- }
- }
- FXSYS_memcpy32(dst_plt, pPalette, sizeof(FX_DWORD) * 256);
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_Rgb2PltRgb8(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt, void* pIccTransform)
-{
- ICodec_IccModule* pIccModule = NULL;
- if (pIccTransform) {
- pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- }
- FX_BOOL ret = _ConvertBuffer_Rgb2PltRgb8_NoTransform(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, dst_plt);
- if (ret && pIccTransform) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- for (int i = 0; i < 256; i++) {
- FX_ARGB* plt = dst_plt + i;
- FX_ARGB plt_entry = FXARGB_TODIB(*plt);
- pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&plt_entry, (FX_LPCBYTE)&plt_entry, 1);
- *plt = FXARGB_TODIB(plt_entry);
- }
- }
- return ret;
-}
-FX_BOOL _ConvertBuffer_1bppMask2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
-{
- int comps = (dst_format & 0xff) / 8;
- FX_BYTE set_gray, reset_gray;
- set_gray = 0xff;
- reset_gray = 0x00;
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
- for (int col = src_left; col < src_left + width; col ++) {
- if (src_scan[col / 8] & (1 << (7 - col % 8))) {
- dest_scan[0] = set_gray;
- dest_scan[1] = set_gray;
- dest_scan[2] = set_gray;
- } else {
- dest_scan[0] = reset_gray;
- dest_scan[1] = reset_gray;
- dest_scan[2] = reset_gray;
- }
- dest_scan += comps;
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_8bppMask2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
-{
- int comps = (dst_format & 0xff) / 8;
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
- FX_BYTE src_pixel;
- for (int col = 0; col < width; col ++) {
- src_pixel = *src_scan++;
- *dest_scan++ = src_pixel;
- *dest_scan++ = src_pixel;
- *dest_scan = src_pixel;
- dest_scan += comps - 2;
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_1bppPlt2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- int comps = (dst_format & 0xff) / 8;
- FX_DWORD* src_plt = pSrcBitmap->GetPalette();
- FX_DWORD plt[2];
- FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
- if (pSrcBitmap->IsCmykImage()) {
- plt[0] = FXCMYK_TODIB(src_plt[0]);
- plt[1] = FXCMYK_TODIB(src_plt[1]);
- } else {
- bgr_ptr[0] = FXARGB_B(src_plt[0]);
- bgr_ptr[1] = FXARGB_G(src_plt[0]);
- bgr_ptr[2] = FXARGB_R(src_plt[0]);
- bgr_ptr[3] = FXARGB_B(src_plt[1]);
- bgr_ptr[4] = FXARGB_G(src_plt[1]);
- bgr_ptr[5] = FXARGB_R(src_plt[1]);
- }
- if (pIccTransform) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)plt, (FX_LPCBYTE)plt, 2);
- } else {
- if (pSrcBitmap->IsCmykImage()) {
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]),
- bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]);
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1]),
- bgr_ptr[5], bgr_ptr[4], bgr_ptr[3]);
- }
- }
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
- for (int col = src_left; col < src_left + width; col ++) {
- if (src_scan[col / 8] & (1 << (7 - col % 8))) {
- *dest_scan++ = bgr_ptr[3];
- *dest_scan++ = bgr_ptr[4];
- *dest_scan = bgr_ptr[5];
- } else {
- *dest_scan++ = bgr_ptr[0];
- *dest_scan++ = bgr_ptr[1];
- *dest_scan = bgr_ptr[2];
- }
- dest_scan += comps - 2;
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_8bppPlt2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- int comps = (dst_format & 0xff) / 8;
- FX_DWORD* src_plt = pSrcBitmap->GetPalette();
- FX_DWORD plt[256];
- FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
- if (!pSrcBitmap->IsCmykImage()) {
- for (int i = 0; i < 256; i++) {
- *bgr_ptr++ = FXARGB_B(src_plt[i]);
- *bgr_ptr++ = FXARGB_G(src_plt[i]);
- *bgr_ptr++ = FXARGB_R(src_plt[i]);
- }
- bgr_ptr = (FX_LPBYTE)plt;
- }
- if (pIccTransform) {
- if (pSrcBitmap->IsCmykImage()) {
- for (int i = 0; i < 256; i++) {
- plt[i] = FXCMYK_TODIB(src_plt[i]);
- }
- }
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)plt, (FX_LPCBYTE)plt, 256);
- } else {
- if (pSrcBitmap->IsCmykImage()) {
- for (int i = 0; i < 256; i++) {
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]),
- bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]);
- bgr_ptr += 3;
- }
- bgr_ptr = (FX_LPBYTE)plt;
- }
- }
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
- for (int col = 0; col < width; col ++) {
- FX_LPBYTE src_pixel = bgr_ptr + 3 * (*src_scan++);
- *dest_scan++ = *src_pixel++;
- *dest_scan++ = *src_pixel++;
- *dest_scan = *src_pixel++;
- dest_scan += comps - 2;
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_24bppRgb2Rgb24(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- if (pIccTransform) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 3;
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, width);
- }
- } else {
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 3;
- FXSYS_memcpy32(dest_scan, src_scan, width * 3);
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_32bppRgb2Rgb24(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
- for (int col = 0; col < width; col ++) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- src_scan++;
- }
- }
- if (pIccTransform) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- pIccModule->TranslateScanline(pIccTransform, dest_scan, dest_scan, width);
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_Rgb2Rgb32(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- int comps = pSrcBitmap->GetBPP() / 8;
- if (pIccTransform) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * comps;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
- dest_scan += 4;
- src_scan += comps;
- }
- }
- } else {
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * comps;
- for (int col = 0; col < width; col ++) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- dest_scan++;
- src_scan += comps - 3;
- }
- }
- }
- return TRUE;
-}
-FX_BOOL _ConvertBuffer_32bppCmyk2Rgb32(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- if (pIccTransform) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
- for (int col = 0; col < width; col ++) {
- pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
- dest_scan += 4;
- src_scan += 4;
- }
- }
- } else {
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
- for (int col = 0; col < width; col ++) {
- AdobeCMYK_to_sRGB1(src_scan[0], src_scan[1], src_scan[2], src_scan[3],
- dest_scan[2], dest_scan[1], dest_scan[0]);
- dest_scan += 4;
- src_scan += 4;
- }
- }
- }
- return TRUE;
-}
-FX_BOOL ConvertBuffer(FXDIB_Format dest_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD*& d_pal, void* pIccTransform)
-{
- FXDIB_Format src_format = pSrcBitmap->GetFormat();
- if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
- pIccTransform = NULL;
- }
- switch (dest_format) {
- case FXDIB_Invalid:
- case FXDIB_1bppCmyk:
- case FXDIB_1bppMask:
- case FXDIB_1bppRgb:
- ASSERT(FALSE);
- return FALSE;
- case FXDIB_8bppMask: {
- if ((src_format & 0xff) == 1) {
- if (pSrcBitmap->GetPalette()) {
- return _ConvertBuffer_1bppPlt2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return _ConvertBuffer_1bppMask2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
- } else if ((src_format & 0xff) == 8) {
- if (pSrcBitmap->GetPalette()) {
- return _ConvertBuffer_8bppPlt2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return _ConvertBuffer_8bppMask2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
- } else if ((src_format & 0xff) >= 24) {
- return _ConvertBuffer_RgbOrCmyk2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return FALSE;
- }
- case FXDIB_8bppRgb:
- case FXDIB_8bppRgba: {
- if ((src_format & 0xff) == 8 && pSrcBitmap->GetPalette() == NULL) {
- return ConvertBuffer(FXDIB_8bppMask, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform);
- }
- d_pal = FX_Alloc(FX_DWORD, 256);
- if (!d_pal) {
- return FALSE;
- }
- FXSYS_memset32(d_pal, 0, sizeof(FX_DWORD) * 256);
- if (((src_format & 0xff) == 1 || (src_format & 0xff) == 8) && pSrcBitmap->GetPalette()) {
- return _ConvertBuffer_Plt2PltRgb8(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform);
- } else if ((src_format & 0xff) >= 24) {
- return _ConvertBuffer_Rgb2PltRgb8(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform);
- }
- return FALSE;
- }
- case FXDIB_Rgb:
- case FXDIB_Rgba: {
- if ((src_format & 0xff) == 1) {
- if (pSrcBitmap->GetPalette()) {
- return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
- } else if ((src_format & 0xff) == 8) {
- if (pSrcBitmap->GetPalette()) {
- return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
- } else if ((src_format & 0xff) == 24) {
- return _ConvertBuffer_24bppRgb2Rgb24(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- } else if ((src_format & 0xff) == 32) {
- return _ConvertBuffer_32bppRgb2Rgb24(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return FALSE;
- }
- case FXDIB_Argb:
- case FXDIB_Rgb32: {
- if ((src_format & 0xff) == 1) {
- if (pSrcBitmap->GetPalette()) {
- return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
- } else if ((src_format & 0xff) == 8) {
- if (pSrcBitmap->GetPalette()) {
- return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
- } else if ((src_format & 0xff) >= 24) {
- if (src_format & 0x0400) {
- return _ConvertBuffer_32bppCmyk2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return _ConvertBuffer_Rgb2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
- }
- return FALSE;
- }
- default:
- return FALSE;
- }
- return FALSE;
-}
-CFX_DIBitmap* CFX_DIBSource::CloneConvert(FXDIB_Format dest_format, const FX_RECT* pClip, void* pIccTransform) const
-{
- if(dest_format == GetFormat() && pIccTransform == NULL) {
- return Clone(pClip);
- }
- if (pClip) {
- CFX_DIBitmap* pClone = Clone(pClip);
- if (pClone == NULL) {
- return NULL;
- }
- if(!pClone->ConvertFormat(dest_format, pIccTransform)) {
- delete pClone;
- return NULL;
- }
- return pClone;
- }
- CFX_DIBitmap* pClone = FX_NEW CFX_DIBitmap;
- if (!pClone) {
- return NULL;
- }
- if(!pClone->Create(m_Width, m_Height, dest_format)) {
- delete pClone;
- return NULL;
- }
- FX_BOOL ret = TRUE;
- CFX_DIBitmap* pSrcAlpha = NULL;
- if (m_AlphaFlag & 2) {
- pSrcAlpha = (GetFormat() == FXDIB_Argb) ? GetAlphaMask() : m_pAlphaMask;
- if (pSrcAlpha == NULL) {
- delete pClone;
- return NULL;
- }
- }
- if (dest_format & 0x0200) {
- if (dest_format == FXDIB_Argb)
- ret = pSrcAlpha ?
- pClone->LoadChannel(FXDIB_Alpha, pSrcAlpha, FXDIB_Alpha) :
- pClone->LoadChannel(FXDIB_Alpha, 0xff);
- else {
- ret = pClone->CopyAlphaMask(pSrcAlpha);
- }
- }
- if (pSrcAlpha && pSrcAlpha != m_pAlphaMask) {
- delete pSrcAlpha;
- pSrcAlpha = NULL;
- }
- if (!ret) {
- delete pClone;
- return NULL;
- }
- FX_DWORD* pal_8bpp = NULL;
- ret = ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(), m_Width, m_Height, this, 0, 0, pal_8bpp, pIccTransform);
- if (!ret) {
- if (pal_8bpp) {
- FX_Free(pal_8bpp);
- }
- delete pClone;
- return NULL;
- }
- if (pal_8bpp) {
- pClone->CopyPalette(pal_8bpp);
- FX_Free(pal_8bpp);
- pal_8bpp = NULL;
- }
- return pClone;
-}
-FX_BOOL CFX_DIBitmap::ConvertFormat(FXDIB_Format dest_format, void* pIccTransform)
-{
- FXDIB_Format src_format = GetFormat();
- if (dest_format == src_format && pIccTransform == NULL) {
- return TRUE;
- }
- if (dest_format == FXDIB_8bppMask && src_format == FXDIB_8bppRgb && m_pPalette == NULL) {
- m_AlphaFlag = 1;
- return TRUE;
- }
- if (dest_format == FXDIB_Argb && src_format == FXDIB_Rgb32 && pIccTransform == NULL) {
- m_AlphaFlag = 2;
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE scanline = m_pBuffer + row * m_Pitch + 3;
- for (int col = 0; col < m_Width; col ++) {
- *scanline = 0xff;
- scanline += 4;
- }
- }
- return TRUE;
- }
- int dest_bpp = dest_format & 0xff;
- int dest_pitch = (dest_bpp * m_Width + 31) / 32 * 4;
- FX_LPBYTE dest_buf = FX_AllocNL(FX_BYTE, dest_pitch * m_Height + 4);
- if (dest_buf == NULL) {
- return FALSE;
- }
- CFX_DIBitmap* pAlphaMask = NULL;
- if (dest_format == FXDIB_Argb) {
- FXSYS_memset8(dest_buf, 0xff, dest_pitch * m_Height + 4);
- if (m_pAlphaMask) {
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE pDstScanline = dest_buf + row * dest_pitch + 3;
- FX_LPCBYTE pSrcScanline = m_pAlphaMask->GetScanline(row);
- for (int col = 0; col < m_Width; col ++) {
- *pDstScanline = *pSrcScanline++;
- pDstScanline += 4;
- }
- }
- }
- } else if (dest_format & 0x0200) {
- if (src_format == FXDIB_Argb) {
- pAlphaMask = GetAlphaMask();
- if (pAlphaMask == NULL) {
- FX_Free(dest_buf);
- return FALSE;
- }
- } else {
- if (m_pAlphaMask == NULL) {
- if (!BuildAlphaMask()) {
- FX_Free(dest_buf);
- return FALSE;
- }
- pAlphaMask = m_pAlphaMask;
- m_pAlphaMask = NULL;
- } else {
- pAlphaMask = m_pAlphaMask;
- }
- }
- }
- FX_BOOL ret = FALSE;
- FX_DWORD* pal_8bpp = NULL;
- ret = ConvertBuffer(dest_format, dest_buf, dest_pitch, m_Width, m_Height, this, 0, 0, pal_8bpp, pIccTransform);
- if (!ret) {
- if (pal_8bpp) {
- FX_Free(pal_8bpp);
- }
- if (pAlphaMask != m_pAlphaMask) {
- delete pAlphaMask;
- }
- if (dest_buf) {
- FX_Free(dest_buf);
- }
- return FALSE;
- }
- if (m_pAlphaMask && pAlphaMask != m_pAlphaMask) {
- delete m_pAlphaMask;
- }
- m_pAlphaMask = pAlphaMask;
- if (m_pPalette) {
- FX_Free(m_pPalette);
- }
- m_pPalette = pal_8bpp;
- if (!m_bExtBuf) {
- FX_Free(m_pBuffer);
- }
- m_bExtBuf = FALSE;
- m_pBuffer = dest_buf;
- m_bpp = (FX_BYTE)dest_format;
- m_AlphaFlag = (FX_BYTE)(dest_format >> 8);
- m_Pitch = dest_pitch;
- return TRUE;
-}
+// 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 "../../../include/fxge/fx_dib.h"
+#include "../../../include/fxge/fx_ge.h"
+#include "../../../include/fxcodec/fx_codec.h"
+const FX_DWORD g_dwWinPalette[256] = {
+ 0xff000000, 0xff800000, 0xff008000, 0xff808000, 0xff000080, 0xff800080,
+ 0xff008080, 0xff808080, 0xffC0DCC0, 0xffA6CAF0, 0xff2A3FAA, 0xff2A3FFF,
+ 0xff2A5F00, 0xff2A5F55, 0xff2A5FAA, 0xff2A5FFF, 0xff2A7F00, 0xff2A7F55,
+ 0xff2A7FAA, 0xff2A7FFF, 0xff2A9F00, 0xff2A9F55, 0xff2A9FAA, 0xff2A9FFF,
+ 0xff2ABF00, 0xff2ABF55, 0xff2ABFAA, 0xff2ABFFF, 0xff2ADF00, 0xff2ADF55,
+ 0xff2ADFAA, 0xff2ADFFF, 0xff2AFF00, 0xff2AFF55, 0xff2AFFAA, 0xff2AFFFF,
+ 0xff550000, 0xff550055, 0xff5500AA, 0xff5500FF, 0xff551F00, 0xff551F55,
+ 0xff551FAA, 0xff551FFF, 0xff553F00, 0xff553F55, 0xff553FAA, 0xff553FFF,
+ 0xff555F00, 0xff555F55, 0xff555FAA, 0xff555FFF, 0xff557F00, 0xff557F55,
+ 0xff557FAA, 0xff557FFF, 0xff559F00, 0xff559F55, 0xff559FAA, 0xff559FFF,
+ 0xff55BF00, 0xff55BF55, 0xff55BFAA, 0xff55BFFF, 0xff55DF00, 0xff55DF55,
+ 0xff55DFAA, 0xff55DFFF, 0xff55FF00, 0xff55FF55, 0xff55FFAA, 0xff55FFFF,
+ 0xff7F0000, 0xff7F0055, 0xff7F00AA, 0xff7F00FF, 0xff7F1F00, 0xff7F1F55,
+ 0xff7F1FAA, 0xff7F1FFF, 0xff7F3F00, 0xff7F3F55, 0xff7F3FAA, 0xff7F3FFF,
+ 0xff7F5F00, 0xff7F5F55, 0xff7F5FAA, 0xff7F5FFF, 0xff7F7F00, 0xff7F7F55,
+ 0xff7F7FAA, 0xff7F7FFF, 0xff7F9F00, 0xff7F9F55, 0xff7F9FAA, 0xff7F9FFF,
+ 0xff7FBF00, 0xff7FBF55, 0xff7FBFAA, 0xff7FBFFF, 0xff7FDF00, 0xff7FDF55,
+ 0xff7FDFAA, 0xff7FDFFF, 0xff00FF7F, 0xff7FFF55, 0xff7FFFAA, 0xff7FFFFF,
+ 0xffAA0000, 0xffAA0055, 0xffAA00AA, 0xffAA00FF, 0xffAA1F00, 0xffAA1F55,
+ 0xffAA1FAA, 0xffAA1FFF, 0xffAA3F00, 0xffAA3F55, 0xffAA3FAA, 0xffAA3FFF,
+ 0xffAA5F00, 0xffAA5F55, 0xffAA5FAA, 0xffAA5FFF, 0xffAA7F00, 0xffAA7F55,
+ 0xffAA7FAA, 0xffAA7FFF, 0xffAA9F00, 0xffAA9F55, 0xffAA9FAA, 0xffAA9FFF,
+ 0xffAABF00, 0xffAABF55, 0xffAABFAA, 0xffAABFFF, 0xffAADF00, 0xffAADF55,
+ 0xffAADFAA, 0xffAADFFF, 0xffAAFF00, 0xffAAFF55, 0xffAAFFAA, 0xffAAFFFF,
+ 0xffD40000, 0xffD40055, 0xffD400AA, 0xffD400FF, 0xffD41F00, 0xffD41F55,
+ 0xffD41FAA, 0xffD41FFF, 0xffD43F00, 0xffD43F55, 0xffD43FAA, 0xffD43FFF,
+ 0xffD45F00, 0xffD45F55, 0xffD45FAA, 0xffD45FFF, 0xffD47F00, 0xffD47F55,
+ 0xffD47FAA, 0xffD4F7FF, 0xffD49F00, 0xffD49F55, 0xffD49FAA, 0xffD49FFF,
+ 0xffD4BF00, 0xffD4BF55, 0xffD4BFAA, 0xffD4BFFF, 0xffD4DF00, 0xffD4DF55,
+ 0xffD4DFAA, 0xffD4DFFF, 0xffD4FF00, 0xffD4FF55, 0xffD4FFAA, 0xffD4FFFF,
+ 0xffFF0055, 0xffFF00AA, 0xffFF1F00, 0xffFF1F55, 0xffFF1FAA, 0xffFF1FFF,
+ 0xffFF3F00, 0xffFF3F55, 0xffFF3FAA, 0xffFF3FFF, 0xffFF5F00, 0xffFF5F55,
+ 0xffFF5FAA, 0xffFF5FFF, 0xffFF7F00, 0xffFF7F55, 0xffFF7FAA, 0xffFF7FFF,
+ 0xffFF9F00, 0xffFF9F55, 0xffFF9FAA, 0xffFF9FFF, 0xffFFBF00, 0xffFFBF55,
+ 0xffFFBFAA, 0xffFFBFFF, 0xffFFDF00, 0xffFFDF55, 0xffFFDFAA, 0xffFFDFFF,
+ 0xffFFFF55, 0xffFFFFAA, 0xffCCCCFF, 0xffFFCCFF, 0xff33FFFF, 0xff66FFFF,
+ 0xff99FFFF, 0xffCCFFFF, 0xff007F00, 0xff007F55, 0xff007FAA, 0xff007FFF,
+ 0xff009F00, 0xff009F55, 0xff009FAA, 0xff009FFF, 0xff00BF00, 0xff00BF55,
+ 0xff00BFAA, 0xff00BFFF, 0xff00DF00, 0xff00DF55, 0xff00DFAA, 0xff00DFFF,
+ 0xff00FF55, 0xff00FFAA, 0xff2A0000, 0xff2A0055, 0xff2A00AA, 0xff2A00FF,
+ 0xff2A1F00, 0xff2A1F55, 0xff2A1FAA, 0xff2A1FFF, 0xff2A3F00, 0xff2A3F55,
+ 0xffFFFBF0, 0xffA0A0A4, 0xff808080, 0xffFF0000, 0xff00FF00, 0xffFF0000,
+ 0xff0000FF, 0xffFF00FF, 0xff00FFFF, 0xffFFFFFF
+};
+const FX_DWORD g_dwMacPalette[256] = {
+ 0xffFFFFFF, 0xffFFFFCC, 0xffFFFF99, 0xffFFFF66, 0xffFFFF33, 0xffFFFF00,
+ 0xffFFCCFF, 0xffFFCCCC, 0xffFFCC99, 0xffFFCC66, 0xffFFCC33, 0xffFFCC00,
+ 0xffFF99FF, 0xffFF99CC, 0xffFF9999, 0xffFF9966, 0xffFF9933, 0xffFF9900,
+ 0xffFF66FF, 0xffFF66CC, 0xffFF6699, 0xffFF6666, 0xffFF6633, 0xffFF6600,
+ 0xffFF33FF, 0xffFF33CC, 0xffFF3399, 0xffFF3366, 0xffFF3333, 0xffFF3300,
+ 0xffFF00FF, 0xffFF00CC, 0xffFF0099, 0xffFF0066, 0xffFF0033, 0xffFF0000,
+ 0xffCCFFFF, 0xffCCFFCC, 0xffCCFF99, 0xffCCFF66, 0xffCCFF33, 0xffCCFF00,
+ 0xffCCCCFF, 0xffCCCCCC, 0xffCCCC99, 0xffCCCC66, 0xffCCCC33, 0xffCCCC00,
+ 0xffCC99FF, 0xffCC99CC, 0xffCC9999, 0xffCC9966, 0xffCC9933, 0xffCC9900,
+ 0xffCC66FF, 0xffCC66CC, 0xffCC6699, 0xffCC6666, 0xffCC6633, 0xffCC6600,
+ 0xffCC33FF, 0xffCC33CC, 0xffCC3399, 0xffCC3366, 0xffCC3333, 0xffCC3300,
+ 0xffCC00FF, 0xffCC00CC, 0xffCC0099, 0xffCC0066, 0xffCC0033, 0xffCC0000,
+ 0xff99FFFF, 0xff99FFCC, 0xff99FF99, 0xff99FF66, 0xff99FF33, 0xff99FF00,
+ 0xff99CCFF, 0xff99CCCC, 0xff99CC99, 0xff99CC66, 0xff99CC33, 0xff99CC00,
+ 0xff9999FF, 0xff9999CC, 0xff999999, 0xff999966, 0xff999933, 0xff999900,
+ 0xff9966FF, 0xff9966CC, 0xff996699, 0xff996666, 0xff996633, 0xff996600,
+ 0xff9933FF, 0xff9933CC, 0xff993399, 0xff993366, 0xff993333, 0xff993300,
+ 0xff9900FF, 0xff9900CC, 0xff990099, 0xff990066, 0xff990033, 0xff990000,
+ 0xff66FFFF, 0xff66FFCC, 0xff66FF99, 0xff66FF66, 0xff66FF33, 0xff66FF00,
+ 0xff66CCFF, 0xff66CCCC, 0xff66CC99, 0xff66CC66, 0xff66CC33, 0xff66CC00,
+ 0xff6699FF, 0xff6699CC, 0xff669999, 0xff669966, 0xff669933, 0xff669900,
+ 0xff6666FF, 0xff6666CC, 0xff666699, 0xff666666, 0xff666633, 0xff666600,
+ 0xff6633FF, 0xff6633CC, 0xff663399, 0xff663366, 0xff663333, 0xff663300,
+ 0xff6600FF, 0xff6600CC, 0xff660099, 0xff660066, 0xff660033, 0xff660000,
+ 0xff33FFFF, 0xff33FFCC, 0xff33FF99, 0xff33FF66, 0xff33FF33, 0xff33FF00,
+ 0xff33CCFF, 0xff33CCCC, 0xff33CC99, 0xff33CC66, 0xff33CC33, 0xff33CC00,
+ 0xff3399FF, 0xff3399CC, 0xff339999, 0xff339966, 0xff339933, 0xff339900,
+ 0xff3366FF, 0xff3366CC, 0xff336699, 0xff336666, 0xff336633, 0xff336600,
+ 0xff3333FF, 0xff3333CC, 0xff333399, 0xff333366, 0xff333333, 0xff333300,
+ 0xff3300FF, 0xff3300CC, 0xff330099, 0xff330066, 0xff330033, 0xff330000,
+ 0xff00FFFF, 0xff00FFCC, 0xff00FF99, 0xff00FF66, 0xff00FF33, 0xff00FF00,
+ 0xff00CCFF, 0xff00CCCC, 0xff00CC99, 0xff00CC66, 0xff00CC33, 0xff00CC00,
+ 0xff0099FF, 0xff0099CC, 0xff009999, 0xff009966, 0xff009933, 0xff009900,
+ 0xff0066FF, 0xff0066CC, 0xff006699, 0xff006666, 0xff006633, 0xff006600,
+ 0xff0033FF, 0xff0033CC, 0xff003399, 0xff003366, 0xff003333, 0xff003300,
+ 0xff0000FF, 0xff0000CC, 0xff000099, 0xff000066, 0xff000033,
+ 0xffEE0000, 0xffDD0000, 0xffBB0000, 0xffAA0000, 0xff880000, 0xff770000,
+ 0xff550000, 0xff440000, 0xff220000, 0xff110000, 0xff00EE00, 0xff00DD00,
+ 0xff00BB00, 0xff00AA00, 0xff008800, 0xff007700, 0xff005500, 0xff004400,
+ 0xff002200, 0xff001100, 0xff0000EE, 0xff0000DD, 0xff0000BB, 0xff0000AA,
+ 0xff000088, 0xff000077, 0xff000055, 0xff000044, 0xff000022, 0xff000011,
+ 0xffEEEEEE, 0xffDDDDDD, 0xffBBBBBB, 0xffAAAAAA, 0xff888888, 0xff777777,
+ 0xff555555, 0xff444444, 0xff222222, 0xff111111, 0xff000000
+};
+class CFX_Palette : public CFX_Object
+{
+public:
+ CFX_Palette();
+ ~CFX_Palette();
+public:
+ FX_BOOL BuildPalette(const CFX_DIBSource* pBitmap, int dwPaletteType);
+ FX_DWORD* GetPalette() const
+ {
+ return m_pPalette;
+ }
+
+ FX_DWORD* GetColorLut()const
+ {
+ return m_cLut;
+ }
+ FX_DWORD* GetAmountLut()const
+ {
+ return m_aLut;
+ }
+ FX_INT32 Getlut()const
+ {
+ return m_lut;
+ }
+protected:
+ FX_DWORD* m_pPalette;
+ FX_DWORD* m_cLut;
+ FX_DWORD* m_aLut;
+ int m_lut;
+};
+int _Partition(FX_DWORD* alut, FX_DWORD* clut, int l, int r)
+{
+ FX_DWORD p_a = alut[l];
+ FX_DWORD p_c = clut[l];
+ while(l < r) {
+ while(l < r && alut[r] >= p_a) {
+ r--;
+ }
+ if (l < r) {
+ alut[l] = alut[r];
+ clut[l++] = clut[r];
+ }
+ while(l < r && alut[l] <= p_a) {
+ l++;
+ }
+ if (l < r) {
+ alut[r] = alut[l];
+ clut[r--] = clut[l];
+ }
+ }
+ alut[l] = p_a;
+ clut[l] = p_c;
+ return l;
+}
+void _Qsort(FX_DWORD* alut, FX_DWORD* clut, int l, int r)
+{
+ if(l < r) {
+ int pI = _Partition(alut, clut, l, r);
+ _Qsort(alut, clut, l, pI - 1);
+ _Qsort(alut, clut, pI + 1, r);
+ }
+}
+void _ColorDecode(FX_DWORD pal_v, FX_BYTE& r, FX_BYTE& g, FX_BYTE& b)
+{
+ r = (FX_BYTE)((pal_v & 0xf00) >> 4);
+ g = (FX_BYTE)(pal_v & 0x0f0);
+ b = (FX_BYTE)((pal_v & 0x00f) << 4);
+}
+void _Obtain_Pal(FX_DWORD* aLut, FX_DWORD*cLut, FX_DWORD* dest_pal, int pal_type, FX_DWORD* win_mac_pal, FX_DWORD lut)
+{
+ int row, col;
+ FX_DWORD lut_1 = lut - 1;
+ if (pal_type == FXDIB_PALETTE_LOC) {
+ for (row = 0; row < 256; row++) {
+ int lut_offset = lut_1 - row;
+ if (lut_offset < 0) {
+ lut_offset += 256;
+ }
+ FX_DWORD color = cLut[lut_offset];
+ FX_BYTE r, g, b;
+ _ColorDecode(color, r, g, b);
+ dest_pal[row] = ((FX_DWORD)r << 16) | ((FX_DWORD)g << 8) | b | 0xff000000;
+ aLut[lut_offset] = row;
+ }
+ } else {
+ for (row = 0; row < 256; row++) {
+ int lut_offset = lut_1 - row;
+ if (lut_offset < 0) {
+ lut_offset += 256;
+ }
+ FX_BYTE r, g, b;
+ _ColorDecode(cLut[lut_offset], r, g, b);
+ int error, min_error = 1000000;
+ int c_index = 0;
+ for (col = 0; col < 256; col++) {
+ FX_DWORD p_color = win_mac_pal[col];
+ int d_r = r - (FX_BYTE)(p_color >> 16);
+ int d_g = g - (FX_BYTE)(p_color >> 8);
+ int d_b = b - (FX_BYTE)p_color;
+ error = d_r * d_r + d_g * d_g + d_b * d_b;
+ if (error < min_error) {
+ min_error = error;
+ c_index = col;
+ }
+ }
+ dest_pal[row] = win_mac_pal[c_index];
+ aLut[lut_offset] = row;
+ }
+ }
+}
+CFX_Palette::CFX_Palette()
+{
+ m_pPalette = NULL;
+ m_cLut = NULL;
+ m_aLut = NULL;
+ m_lut = 0;
+}
+CFX_Palette::~CFX_Palette()
+{
+ if (m_pPalette) {
+ FX_Free(m_pPalette);
+ }
+ if (m_cLut) {
+ FX_Free(m_cLut);
+ }
+ if (m_aLut) {
+ FX_Free(m_aLut);
+ }
+ m_lut = 0;
+}
+FX_BOOL CFX_Palette::BuildPalette(const CFX_DIBSource* pBitmap, int pal_type)
+{
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ if (m_pPalette != NULL) {
+ FX_Free(m_pPalette);
+ }
+ m_pPalette = FX_Alloc(FX_DWORD, 256);
+ if (!m_pPalette) {
+ return FALSE;
+ }
+ FXSYS_memset32(m_pPalette, 0, sizeof(FX_DWORD) * 256);
+ int bpp = pBitmap->GetBPP() / 8;
+ int width = pBitmap->GetWidth();
+ int height = pBitmap->GetHeight();
+ if (m_cLut) {
+ FX_Free(m_cLut);
+ m_cLut = NULL;
+ }
+ if (m_aLut) {
+ FX_Free(m_aLut);
+ m_aLut = NULL;
+ }
+ m_cLut = FX_Alloc(FX_DWORD, 4096);
+ if (!m_cLut) {
+ return FALSE;
+ }
+ m_aLut = FX_Alloc(FX_DWORD, 4096);
+ if (!m_aLut) {
+ return FALSE;
+ }
+ FXSYS_memset32(m_aLut, 0, sizeof(FX_DWORD) * 4096);
+ FXSYS_memset32(m_cLut, 0, sizeof(FX_DWORD) * 4096);
+ int row, col;
+ m_lut = 0;
+ for (row = 0; row < height; row++) {
+ FX_BYTE* scan_line = (FX_BYTE*)pBitmap->GetScanline(row);
+ for (col = 0; col < width; col++) {
+ FX_BYTE* src_port = scan_line + col * bpp;
+ FX_DWORD b = src_port[0] & 0xf0;
+ FX_DWORD g = src_port[1] & 0xf0;
+ FX_DWORD r = src_port[2] & 0xf0;
+ FX_DWORD index = (r << 4) + g + (b >> 4);
+ m_aLut[index]++;
+ }
+ }
+ for (row = 0; row < 4096; row++) {
+ if (m_aLut[row] != 0) {
+ m_aLut[m_lut] = m_aLut[row];
+ m_cLut[m_lut] = row;
+ m_lut++;
+ }
+ }
+ _Qsort(m_aLut, m_cLut, 0, m_lut - 1);
+ FX_DWORD* win_mac_pal = NULL;
+ if (pal_type == FXDIB_PALETTE_WIN) {
+ win_mac_pal = (FX_DWORD*)g_dwWinPalette;
+ } else if (pal_type == FXDIB_PALETTE_MAC) {
+ win_mac_pal = (FX_DWORD*)g_dwMacPalette;
+ }
+ _Obtain_Pal(m_aLut, m_cLut, m_pPalette, pal_type, win_mac_pal, m_lut);
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_1bppMask2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
+{
+ FX_BYTE set_gray, reset_gray;
+ set_gray = 0xff;
+ reset_gray = 0x00;
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FXSYS_memset8(dest_scan, reset_gray, width);
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
+ for (int col = src_left; col < src_left + width; col ++) {
+ if (src_scan[col / 8] & (1 << (7 - col % 8))) {
+ *dest_scan = set_gray;
+ }
+ dest_scan ++;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_8bppMask2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
+{
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
+ FXSYS_memcpy32(dest_scan, src_scan, width);
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_1bppPlt2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ FX_DWORD* src_plt = pSrcBitmap->GetPalette();
+ FX_BYTE gray[2];
+ if (pIccTransform) {
+ FX_DWORD plt[2];
+ if (pSrcBitmap->IsCmykImage()) {
+ plt[0] = FXCMYK_TODIB(src_plt[0]);
+ plt[1] = FXCMYK_TODIB(src_plt[1]);
+ } else {
+ FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
+ bgr_ptr[0] = FXARGB_B(src_plt[0]);
+ bgr_ptr[1] = FXARGB_G(src_plt[0]);
+ bgr_ptr[2] = FXARGB_R(src_plt[0]);
+ bgr_ptr[3] = FXARGB_B(src_plt[1]);
+ bgr_ptr[4] = FXARGB_G(src_plt[1]);
+ bgr_ptr[5] = FXARGB_R(src_plt[1]);
+ }
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ pIccModule->TranslateScanline(pIccTransform, gray, (FX_LPCBYTE)plt, 2);
+ } else {
+ FX_BYTE reset_r, reset_g, reset_b,
+ set_r, set_g, set_b;
+ if (pSrcBitmap->IsCmykImage()) {
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]),
+ reset_r, reset_g, reset_b);
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1]),
+ set_r, set_g, set_b);
+ } else {
+ reset_r = FXARGB_R(src_plt[0]);
+ reset_g = FXARGB_G(src_plt[0]);
+ reset_b = FXARGB_B(src_plt[0]);
+ set_r = FXARGB_R(src_plt[1]);
+ set_g = FXARGB_G(src_plt[1]);
+ set_b = FXARGB_B(src_plt[1]);
+ }
+ gray[0] = FXRGB2GRAY(reset_r, reset_g, reset_b);
+ gray[1] = FXRGB2GRAY(set_r, set_g, set_b);
+ }
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FXSYS_memset8(dest_scan, gray[0], width);
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
+ for (int col = src_left; col < src_left + width; col ++) {
+ if (src_scan[col / 8] & (1 << (7 - col % 8))) {
+ *dest_scan = gray[1];
+ }
+ dest_scan ++;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_8bppPlt2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ FX_DWORD* src_plt = pSrcBitmap->GetPalette();
+ FX_BYTE gray[256];
+ if (pIccTransform) {
+ FX_DWORD plt[256];
+ if (pSrcBitmap->IsCmykImage()) {
+ for (int i = 0; i < 256; i ++) {
+ plt[i] = FXCMYK_TODIB(src_plt[i]);
+ }
+ } else {
+ FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
+ for (int i = 0; i < 256; i ++) {
+ *bgr_ptr++ = FXARGB_B(src_plt[i]);
+ *bgr_ptr++ = FXARGB_G(src_plt[i]);
+ *bgr_ptr++ = FXARGB_R(src_plt[i]);
+ }
+ }
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ pIccModule->TranslateScanline(pIccTransform, gray, (FX_LPCBYTE)plt, 256);
+ } else {
+ if (pSrcBitmap->IsCmykImage()) {
+ FX_BYTE r, g, b;
+ for (int i = 0; i < 256; i ++) {
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]),
+ r, g, b);
+ gray[i] = FXRGB2GRAY(r, g, b);
+ }
+ } else
+ for (int i = 0; i < 256; i ++) {
+ gray[i] = FXRGB2GRAY(FXARGB_R(src_plt[i]), FXARGB_G(src_plt[i]), FXARGB_B(src_plt[i]));
+ }
+ }
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
+ for (int col = 0; col < width; col ++) {
+ *dest_scan++ = gray[*src_scan++];
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_RgbOrCmyk2Gray(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ int Bpp = pSrcBitmap->GetBPP() / 8;
+ if (pIccTransform) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ if (Bpp == 3 || pSrcBitmap->IsCmykImage()) {
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, width);
+ }
+ } else {
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
+ dest_scan++;
+ src_scan += 4;
+ }
+ }
+ }
+ } else {
+ if (pSrcBitmap->IsCmykImage()) {
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
+ for (int col = 0; col < width; col ++) {
+ FX_BYTE r, g, b;
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue((FX_DWORD)src_scan[0]), FXSYS_GetMValue((FX_DWORD)src_scan[1]), FXSYS_GetYValue((FX_DWORD)src_scan[2]), FXSYS_GetKValue((FX_DWORD)src_scan[3]),
+ r, g, b);
+ *dest_scan++ = FXRGB2GRAY(r, g, b);
+ src_scan += 4;
+ }
+ }
+ } else
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
+ for (int col = 0; col < width; col ++) {
+ *dest_scan++ = FXRGB2GRAY(src_scan[2], src_scan[1], src_scan[0]);
+ src_scan += Bpp;
+ }
+ }
+ }
+ return TRUE;
+}
+inline void _ConvertBuffer_IndexCopy(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
+{
+ if (pSrcBitmap->GetBPP() == 1) {
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FXSYS_memset32(dest_scan, 0, width);
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
+ for (int col = src_left; col < src_left + width; col ++) {
+ if (src_scan[col / 8] & (1 << (7 - col % 8))) {
+ *dest_scan = 1;
+ }
+ dest_scan ++;
+ }
+ }
+ } else {
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
+ FXSYS_memcpy32(dest_scan, src_scan, width);
+ }
+ }
+}
+FX_BOOL _ConvertBuffer_Plt2PltRgb8(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt, void* pIccTransform)
+{
+ _ConvertBuffer_IndexCopy(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
+ FX_DWORD* src_plt = pSrcBitmap->GetPalette();
+ int plt_size = pSrcBitmap->GetPaletteSize();
+ if (pIccTransform) {
+ FX_DWORD plt[256];
+ FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
+ if (pSrcBitmap->IsCmykImage()) {
+ for (int i = 0; i < plt_size; i ++) {
+ plt[i] = FXCMYK_TODIB(src_plt[i]);
+ }
+ } else {
+ for (int i = 0; i < plt_size; i ++) {
+ *bgr_ptr++ = FXARGB_B(src_plt[i]);
+ *bgr_ptr++ = FXARGB_G(src_plt[i]);
+ *bgr_ptr++ = FXARGB_R(src_plt[i]);
+ }
+ bgr_ptr = (FX_LPBYTE)plt;
+ }
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)plt, (FX_LPCBYTE)plt, plt_size);
+ for (int i = 0; i < plt_size; i ++) {
+ dst_plt[i] = FXARGB_MAKE(0xff, bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]);
+ bgr_ptr += 3;
+ }
+ } else {
+ if (pSrcBitmap->IsCmykImage()) {
+ for (int i = 0; i < plt_size; i ++) {
+ FX_BYTE r, g, b;
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]),
+ r, g, b);
+ dst_plt[i] = FXARGB_MAKE(0xff, r, g, b);
+ }
+ } else {
+ FXSYS_memcpy32(dst_plt, src_plt, plt_size * 4);
+ }
+ }
+ return TRUE;
+}
+inline FX_BOOL _ConvertBuffer_Rgb2PltRgb8_NoTransform(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt)
+{
+ int bpp = pSrcBitmap->GetBPP() / 8;
+ int row, col;
+ CFX_Palette palette;
+ palette.BuildPalette(pSrcBitmap, FXDIB_PALETTE_LOC);
+ FX_DWORD* cLut = palette.GetColorLut();
+ FX_DWORD* aLut = palette.GetAmountLut();
+ if (cLut == NULL || aLut == NULL) {
+ return FALSE;
+ }
+ int lut = palette.Getlut();
+ FX_DWORD* pPalette = palette.GetPalette();
+ if (lut > 256) {
+ int err, min_err;
+ int lut_256 = lut - 256;
+ for (row = 0; row < lut_256; row++) {
+ min_err = 1000000;
+ FX_BYTE r, g, b;
+ _ColorDecode(cLut[row], r, g, b);
+ int clrindex = 0;
+ for (int col = 0; col < 256; col++) {
+ FX_DWORD p_color = *(pPalette + col);
+ int d_r = r - (FX_BYTE)(p_color >> 16);
+ int d_g = g - (FX_BYTE)(p_color >> 8);
+ int d_b = b - (FX_BYTE)(p_color);
+ err = d_r * d_r + d_g * d_g + d_b * d_b;
+ if (err < min_err) {
+ min_err = err;
+ clrindex = col;
+ }
+ }
+ aLut[row] = clrindex;
+ }
+ }
+ FX_INT32 lut_1 = lut - 1;
+ for (row = 0; row < height; row ++) {
+ FX_BYTE* src_scan = (FX_BYTE*)pSrcBitmap->GetScanline(src_top + row) + src_left;
+ FX_BYTE* dest_scan = dest_buf + row * dest_pitch;
+ for (col = 0; col < width; col++) {
+ FX_BYTE* src_port = src_scan + col * bpp;
+ int r = src_port[2] & 0xf0;
+ int g = src_port[1] & 0xf0;
+ int b = src_port[0] & 0xf0;
+ FX_DWORD clrindex = (r << 4) + g + (b >> 4);
+ for (int i = lut_1; i >= 0; i--)
+ if (clrindex == cLut[i]) {
+ *(dest_scan + col) = (FX_BYTE)(aLut[i]);
+ break;
+ }
+ }
+ }
+ FXSYS_memcpy32(dst_plt, pPalette, sizeof(FX_DWORD) * 256);
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_Rgb2PltRgb8(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD* dst_plt, void* pIccTransform)
+{
+ ICodec_IccModule* pIccModule = NULL;
+ if (pIccTransform) {
+ pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ }
+ FX_BOOL ret = _ConvertBuffer_Rgb2PltRgb8_NoTransform(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, dst_plt);
+ if (ret && pIccTransform) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ for (int i = 0; i < 256; i++) {
+ FX_ARGB* plt = dst_plt + i;
+ FX_ARGB plt_entry = FXARGB_TODIB(*plt);
+ pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)&plt_entry, (FX_LPCBYTE)&plt_entry, 1);
+ *plt = FXARGB_TODIB(plt_entry);
+ }
+ }
+ return ret;
+}
+FX_BOOL _ConvertBuffer_1bppMask2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
+{
+ int comps = (dst_format & 0xff) / 8;
+ FX_BYTE set_gray, reset_gray;
+ set_gray = 0xff;
+ reset_gray = 0x00;
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
+ for (int col = src_left; col < src_left + width; col ++) {
+ if (src_scan[col / 8] & (1 << (7 - col % 8))) {
+ dest_scan[0] = set_gray;
+ dest_scan[1] = set_gray;
+ dest_scan[2] = set_gray;
+ } else {
+ dest_scan[0] = reset_gray;
+ dest_scan[1] = reset_gray;
+ dest_scan[2] = reset_gray;
+ }
+ dest_scan += comps;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_8bppMask2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top)
+{
+ int comps = (dst_format & 0xff) / 8;
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
+ FX_BYTE src_pixel;
+ for (int col = 0; col < width; col ++) {
+ src_pixel = *src_scan++;
+ *dest_scan++ = src_pixel;
+ *dest_scan++ = src_pixel;
+ *dest_scan = src_pixel;
+ dest_scan += comps - 2;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_1bppPlt2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ int comps = (dst_format & 0xff) / 8;
+ FX_DWORD* src_plt = pSrcBitmap->GetPalette();
+ FX_DWORD plt[2];
+ FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
+ if (pSrcBitmap->IsCmykImage()) {
+ plt[0] = FXCMYK_TODIB(src_plt[0]);
+ plt[1] = FXCMYK_TODIB(src_plt[1]);
+ } else {
+ bgr_ptr[0] = FXARGB_B(src_plt[0]);
+ bgr_ptr[1] = FXARGB_G(src_plt[0]);
+ bgr_ptr[2] = FXARGB_R(src_plt[0]);
+ bgr_ptr[3] = FXARGB_B(src_plt[1]);
+ bgr_ptr[4] = FXARGB_G(src_plt[1]);
+ bgr_ptr[5] = FXARGB_R(src_plt[1]);
+ }
+ if (pIccTransform) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)plt, (FX_LPCBYTE)plt, 2);
+ } else {
+ if (pSrcBitmap->IsCmykImage()) {
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[0]), FXSYS_GetMValue(src_plt[0]), FXSYS_GetYValue(src_plt[0]), FXSYS_GetKValue(src_plt[0]),
+ bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]);
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[1]), FXSYS_GetMValue(src_plt[1]), FXSYS_GetYValue(src_plt[1]), FXSYS_GetKValue(src_plt[1]),
+ bgr_ptr[5], bgr_ptr[4], bgr_ptr[3]);
+ }
+ }
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
+ for (int col = src_left; col < src_left + width; col ++) {
+ if (src_scan[col / 8] & (1 << (7 - col % 8))) {
+ *dest_scan++ = bgr_ptr[3];
+ *dest_scan++ = bgr_ptr[4];
+ *dest_scan = bgr_ptr[5];
+ } else {
+ *dest_scan++ = bgr_ptr[0];
+ *dest_scan++ = bgr_ptr[1];
+ *dest_scan = bgr_ptr[2];
+ }
+ dest_scan += comps - 2;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_8bppPlt2Rgb(FXDIB_Format dst_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ int comps = (dst_format & 0xff) / 8;
+ FX_DWORD* src_plt = pSrcBitmap->GetPalette();
+ FX_DWORD plt[256];
+ FX_LPBYTE bgr_ptr = (FX_LPBYTE)plt;
+ if (!pSrcBitmap->IsCmykImage()) {
+ for (int i = 0; i < 256; i++) {
+ *bgr_ptr++ = FXARGB_B(src_plt[i]);
+ *bgr_ptr++ = FXARGB_G(src_plt[i]);
+ *bgr_ptr++ = FXARGB_R(src_plt[i]);
+ }
+ bgr_ptr = (FX_LPBYTE)plt;
+ }
+ if (pIccTransform) {
+ if (pSrcBitmap->IsCmykImage()) {
+ for (int i = 0; i < 256; i++) {
+ plt[i] = FXCMYK_TODIB(src_plt[i]);
+ }
+ }
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ pIccModule->TranslateScanline(pIccTransform, (FX_LPBYTE)plt, (FX_LPCBYTE)plt, 256);
+ } else {
+ if (pSrcBitmap->IsCmykImage()) {
+ for (int i = 0; i < 256; i++) {
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(src_plt[i]), FXSYS_GetMValue(src_plt[i]), FXSYS_GetYValue(src_plt[i]), FXSYS_GetKValue(src_plt[i]),
+ bgr_ptr[2], bgr_ptr[1], bgr_ptr[0]);
+ bgr_ptr += 3;
+ }
+ bgr_ptr = (FX_LPBYTE)plt;
+ }
+ }
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left;
+ for (int col = 0; col < width; col ++) {
+ FX_LPBYTE src_pixel = bgr_ptr + 3 * (*src_scan++);
+ *dest_scan++ = *src_pixel++;
+ *dest_scan++ = *src_pixel++;
+ *dest_scan = *src_pixel++;
+ dest_scan += comps - 2;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_24bppRgb2Rgb24(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ if (pIccTransform) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 3;
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, width);
+ }
+ } else {
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 3;
+ FXSYS_memcpy32(dest_scan, src_scan, width * 3);
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_32bppRgb2Rgb24(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
+ for (int col = 0; col < width; col ++) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ src_scan++;
+ }
+ }
+ if (pIccTransform) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, dest_scan, width);
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_Rgb2Rgb32(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ int comps = pSrcBitmap->GetBPP() / 8;
+ if (pIccTransform) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * comps;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
+ dest_scan += 4;
+ src_scan += comps;
+ }
+ }
+ } else {
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * comps;
+ for (int col = 0; col < width; col ++) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ dest_scan++;
+ src_scan += comps - 3;
+ }
+ }
+ }
+ return TRUE;
+}
+FX_BOOL _ConvertBuffer_32bppCmyk2Rgb32(FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ if (pIccTransform) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
+ for (int col = 0; col < width; col ++) {
+ pIccModule->TranslateScanline(pIccTransform, dest_scan, src_scan, 1);
+ dest_scan += 4;
+ src_scan += 4;
+ }
+ }
+ } else {
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
+ for (int col = 0; col < width; col ++) {
+ AdobeCMYK_to_sRGB1(src_scan[0], src_scan[1], src_scan[2], src_scan[3],
+ dest_scan[2], dest_scan[1], dest_scan[0]);
+ dest_scan += 4;
+ src_scan += 4;
+ }
+ }
+ }
+ return TRUE;
+}
+FX_BOOL ConvertBuffer(FXDIB_Format dest_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD*& d_pal, void* pIccTransform)
+{
+ FXDIB_Format src_format = pSrcBitmap->GetFormat();
+ if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
+ pIccTransform = NULL;
+ }
+ switch (dest_format) {
+ case FXDIB_Invalid:
+ case FXDIB_1bppCmyk:
+ case FXDIB_1bppMask:
+ case FXDIB_1bppRgb:
+ ASSERT(FALSE);
+ return FALSE;
+ case FXDIB_8bppMask: {
+ if ((src_format & 0xff) == 1) {
+ if (pSrcBitmap->GetPalette()) {
+ return _ConvertBuffer_1bppPlt2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return _ConvertBuffer_1bppMask2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
+ } else if ((src_format & 0xff) == 8) {
+ if (pSrcBitmap->GetPalette()) {
+ return _ConvertBuffer_8bppPlt2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return _ConvertBuffer_8bppMask2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
+ } else if ((src_format & 0xff) >= 24) {
+ return _ConvertBuffer_RgbOrCmyk2Gray(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return FALSE;
+ }
+ case FXDIB_8bppRgb:
+ case FXDIB_8bppRgba: {
+ if ((src_format & 0xff) == 8 && pSrcBitmap->GetPalette() == NULL) {
+ return ConvertBuffer(FXDIB_8bppMask, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform);
+ }
+ d_pal = FX_Alloc(FX_DWORD, 256);
+ if (!d_pal) {
+ return FALSE;
+ }
+ FXSYS_memset32(d_pal, 0, sizeof(FX_DWORD) * 256);
+ if (((src_format & 0xff) == 1 || (src_format & 0xff) == 8) && pSrcBitmap->GetPalette()) {
+ return _ConvertBuffer_Plt2PltRgb8(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform);
+ } else if ((src_format & 0xff) >= 24) {
+ return _ConvertBuffer_Rgb2PltRgb8(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, d_pal, pIccTransform);
+ }
+ return FALSE;
+ }
+ case FXDIB_Rgb:
+ case FXDIB_Rgba: {
+ if ((src_format & 0xff) == 1) {
+ if (pSrcBitmap->GetPalette()) {
+ return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
+ } else if ((src_format & 0xff) == 8) {
+ if (pSrcBitmap->GetPalette()) {
+ return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
+ } else if ((src_format & 0xff) == 24) {
+ return _ConvertBuffer_24bppRgb2Rgb24(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ } else if ((src_format & 0xff) == 32) {
+ return _ConvertBuffer_32bppRgb2Rgb24(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return FALSE;
+ }
+ case FXDIB_Argb:
+ case FXDIB_Rgb32: {
+ if ((src_format & 0xff) == 1) {
+ if (pSrcBitmap->GetPalette()) {
+ return _ConvertBuffer_1bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return _ConvertBuffer_1bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
+ } else if ((src_format & 0xff) == 8) {
+ if (pSrcBitmap->GetPalette()) {
+ return _ConvertBuffer_8bppPlt2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return _ConvertBuffer_8bppMask2Rgb(dest_format, dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top);
+ } else if ((src_format & 0xff) >= 24) {
+ if (src_format & 0x0400) {
+ return _ConvertBuffer_32bppCmyk2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return _ConvertBuffer_Rgb2Rgb32(dest_buf, dest_pitch, width, height, pSrcBitmap, src_left, src_top, pIccTransform);
+ }
+ return FALSE;
+ }
+ default:
+ return FALSE;
+ }
+ return FALSE;
+}
+CFX_DIBitmap* CFX_DIBSource::CloneConvert(FXDIB_Format dest_format, const FX_RECT* pClip, void* pIccTransform) const
+{
+ if(dest_format == GetFormat() && pIccTransform == NULL) {
+ return Clone(pClip);
+ }
+ if (pClip) {
+ CFX_DIBitmap* pClone = Clone(pClip);
+ if (pClone == NULL) {
+ return NULL;
+ }
+ if(!pClone->ConvertFormat(dest_format, pIccTransform)) {
+ delete pClone;
+ return NULL;
+ }
+ return pClone;
+ }
+ CFX_DIBitmap* pClone = FX_NEW CFX_DIBitmap;
+ if (!pClone) {
+ return NULL;
+ }
+ if(!pClone->Create(m_Width, m_Height, dest_format)) {
+ delete pClone;
+ return NULL;
+ }
+ FX_BOOL ret = TRUE;
+ CFX_DIBitmap* pSrcAlpha = NULL;
+ if (m_AlphaFlag & 2) {
+ pSrcAlpha = (GetFormat() == FXDIB_Argb) ? GetAlphaMask() : m_pAlphaMask;
+ if (pSrcAlpha == NULL) {
+ delete pClone;
+ return NULL;
+ }
+ }
+ if (dest_format & 0x0200) {
+ if (dest_format == FXDIB_Argb)
+ ret = pSrcAlpha ?
+ pClone->LoadChannel(FXDIB_Alpha, pSrcAlpha, FXDIB_Alpha) :
+ pClone->LoadChannel(FXDIB_Alpha, 0xff);
+ else {
+ ret = pClone->CopyAlphaMask(pSrcAlpha);
+ }
+ }
+ if (pSrcAlpha && pSrcAlpha != m_pAlphaMask) {
+ delete pSrcAlpha;
+ pSrcAlpha = NULL;
+ }
+ if (!ret) {
+ delete pClone;
+ return NULL;
+ }
+ FX_DWORD* pal_8bpp = NULL;
+ ret = ConvertBuffer(dest_format, pClone->GetBuffer(), pClone->GetPitch(), m_Width, m_Height, this, 0, 0, pal_8bpp, pIccTransform);
+ if (!ret) {
+ if (pal_8bpp) {
+ FX_Free(pal_8bpp);
+ }
+ delete pClone;
+ return NULL;
+ }
+ if (pal_8bpp) {
+ pClone->CopyPalette(pal_8bpp);
+ FX_Free(pal_8bpp);
+ pal_8bpp = NULL;
+ }
+ return pClone;
+}
+FX_BOOL CFX_DIBitmap::ConvertFormat(FXDIB_Format dest_format, void* pIccTransform)
+{
+ FXDIB_Format src_format = GetFormat();
+ if (dest_format == src_format && pIccTransform == NULL) {
+ return TRUE;
+ }
+ if (dest_format == FXDIB_8bppMask && src_format == FXDIB_8bppRgb && m_pPalette == NULL) {
+ m_AlphaFlag = 1;
+ return TRUE;
+ }
+ if (dest_format == FXDIB_Argb && src_format == FXDIB_Rgb32 && pIccTransform == NULL) {
+ m_AlphaFlag = 2;
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE scanline = m_pBuffer + row * m_Pitch + 3;
+ for (int col = 0; col < m_Width; col ++) {
+ *scanline = 0xff;
+ scanline += 4;
+ }
+ }
+ return TRUE;
+ }
+ int dest_bpp = dest_format & 0xff;
+ int dest_pitch = (dest_bpp * m_Width + 31) / 32 * 4;
+ FX_LPBYTE dest_buf = FX_AllocNL(FX_BYTE, dest_pitch * m_Height + 4);
+ if (dest_buf == NULL) {
+ return FALSE;
+ }
+ CFX_DIBitmap* pAlphaMask = NULL;
+ if (dest_format == FXDIB_Argb) {
+ FXSYS_memset8(dest_buf, 0xff, dest_pitch * m_Height + 4);
+ if (m_pAlphaMask) {
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE pDstScanline = dest_buf + row * dest_pitch + 3;
+ FX_LPCBYTE pSrcScanline = m_pAlphaMask->GetScanline(row);
+ for (int col = 0; col < m_Width; col ++) {
+ *pDstScanline = *pSrcScanline++;
+ pDstScanline += 4;
+ }
+ }
+ }
+ } else if (dest_format & 0x0200) {
+ if (src_format == FXDIB_Argb) {
+ pAlphaMask = GetAlphaMask();
+ if (pAlphaMask == NULL) {
+ FX_Free(dest_buf);
+ return FALSE;
+ }
+ } else {
+ if (m_pAlphaMask == NULL) {
+ if (!BuildAlphaMask()) {
+ FX_Free(dest_buf);
+ return FALSE;
+ }
+ pAlphaMask = m_pAlphaMask;
+ m_pAlphaMask = NULL;
+ } else {
+ pAlphaMask = m_pAlphaMask;
+ }
+ }
+ }
+ FX_BOOL ret = FALSE;
+ FX_DWORD* pal_8bpp = NULL;
+ ret = ConvertBuffer(dest_format, dest_buf, dest_pitch, m_Width, m_Height, this, 0, 0, pal_8bpp, pIccTransform);
+ if (!ret) {
+ if (pal_8bpp) {
+ FX_Free(pal_8bpp);
+ }
+ if (pAlphaMask != m_pAlphaMask) {
+ delete pAlphaMask;
+ }
+ if (dest_buf) {
+ FX_Free(dest_buf);
+ }
+ return FALSE;
+ }
+ if (m_pAlphaMask && pAlphaMask != m_pAlphaMask) {
+ delete m_pAlphaMask;
+ }
+ m_pAlphaMask = pAlphaMask;
+ if (m_pPalette) {
+ FX_Free(m_pPalette);
+ }
+ m_pPalette = pal_8bpp;
+ if (!m_bExtBuf) {
+ FX_Free(m_pBuffer);
+ }
+ m_bExtBuf = FALSE;
+ m_pBuffer = dest_buf;
+ m_bpp = (FX_BYTE)dest_format;
+ m_AlphaFlag = (FX_BYTE)(dest_format >> 8);
+ m_Pitch = dest_pitch;
+ return TRUE;
+}
diff --git a/core/src/fxge/dib/fx_dib_engine.cpp b/core/src/fxge/dib/fx_dib_engine.cpp
index 3ddbff6409..a51038628e 100644
--- a/core/src/fxge/dib/fx_dib_engine.cpp
+++ b/core/src/fxge/dib/fx_dib_engine.cpp
@@ -1,867 +1,867 @@
-// 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 "../../../include/fxge/fx_dib.h"
-#include "../../../include/fxge/fx_ge.h"
-#include "dib_int.h"
-#include <limits.h>
-extern int SDP_Table[513];
-void CWeightTable::Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, int flags)
-{
- if (m_pWeightTables) {
- FX_Free(m_pWeightTables);
- m_pWeightTables = NULL;
- }
- double scale, base;
- scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len));
- if (dest_len < 0) {
- base = (FX_FLOAT)(src_len);
- } else {
- base = 0;
- }
- int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1;
- m_ItemSize = sizeof(int) * 2 + (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size));
- m_DestMin = dest_min;
- if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) {
- return;
- }
- m_pWeightTables = FX_AllocNL(FX_BYTE, (dest_max - dest_min) * m_ItemSize + 4);
- if (m_pWeightTables == NULL) {
- return;
- }
- FXSYS_memset32(m_pWeightTables, 0, sizeof(FX_BYTE) * ((dest_max - dest_min)*m_ItemSize + 4));
- if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) {
- for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {
- PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
- double src_pos = dest_pixel * scale + scale / 2 + base;
- if (flags & FXDIB_INTERPOL) {
- pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2);
- pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2);
- if (pixel_weights.m_SrcStart < src_min) {
- pixel_weights.m_SrcStart = src_min;
- }
- if (pixel_weights.m_SrcEnd >= src_max) {
- pixel_weights.m_SrcEnd = src_max - 1;
- }
- if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
- pixel_weights.m_Weights[0] = 65536;
- } else {
- pixel_weights.m_Weights[1] = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 65536);
- pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1];
- }
- } else if (flags & FXDIB_BICUBIC_INTERPOL) {
- pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2);
- pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2);
- int start = pixel_weights.m_SrcStart - 1;
- int end = pixel_weights.m_SrcEnd + 1;
- if (start < src_min) {
- start = src_min;
- }
- if (end >= src_max) {
- end = src_max - 1;
- }
- if (pixel_weights.m_SrcStart < src_min) {
- src_pos += src_min - pixel_weights.m_SrcStart;
- pixel_weights.m_SrcStart = src_min;
- }
- if (pixel_weights.m_SrcEnd >= src_max) {
- pixel_weights.m_SrcEnd = src_max - 1;
- }
- int weight;
- weight = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 256);
- if (start == end) {
- pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
- } else if ((start == pixel_weights.m_SrcStart && (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd ||
- end == pixel_weights.m_SrcEnd) && start < end) || (start < pixel_weights.m_SrcStart && pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd && end == pixel_weights.m_SrcEnd)) {
- if (start < pixel_weights.m_SrcStart) {
- pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8;
- pixel_weights.m_Weights[1] = (SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
- } else {
- if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
- pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight]) << 8;
- pixel_weights.m_Weights[1] = SDP_Table[512 - weight] << 8;
- } else {
- pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8;
- pixel_weights.m_Weights[1] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
- }
- }
- if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
- pixel_weights.m_SrcEnd = end;
- }
- if (start < pixel_weights.m_SrcStart) {
- pixel_weights.m_SrcStart = start;
- }
- } else if (start == pixel_weights.m_SrcStart &&
- start < pixel_weights.m_SrcEnd &&
- pixel_weights.m_SrcEnd < end) {
- pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8;
- pixel_weights.m_Weights[1] = SDP_Table[256 - weight] << 8;
- pixel_weights.m_Weights[2] = SDP_Table[512 - weight] << 8;
- pixel_weights.m_SrcEnd = end;
- } else if (start < pixel_weights.m_SrcStart &&
- pixel_weights.m_SrcStart < pixel_weights.m_SrcEnd &&
- pixel_weights.m_SrcEnd == end) {
- pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8;
- pixel_weights.m_Weights[1] = SDP_Table[weight] << 8;
- pixel_weights.m_Weights[2] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
- pixel_weights.m_SrcStart = start;
- } else {
- pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8;
- pixel_weights.m_Weights[1] = SDP_Table[weight] << 8;
- pixel_weights.m_Weights[2] = SDP_Table[256 - weight] << 8;
- pixel_weights.m_Weights[3] = SDP_Table[512 - weight] << 8;
- pixel_weights.m_SrcStart = start;
- pixel_weights.m_SrcEnd = end;
- }
- } else {
- pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos);
- if (pixel_weights.m_SrcStart < src_min) {
- pixel_weights.m_SrcStart = src_min;
- }
- if (pixel_weights.m_SrcEnd >= src_max) {
- pixel_weights.m_SrcEnd = src_max - 1;
- }
- pixel_weights.m_Weights[0] = 65536;
- }
- }
- return;
- }
- for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {
- PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
- double src_start = dest_pixel * scale + base;
- double src_end = src_start + scale;
- int start_i, end_i;
- if (src_start < src_end) {
- start_i = (int)FXSYS_floor((FX_FLOAT)src_start);
- end_i = (int)FXSYS_ceil((FX_FLOAT)src_end);
- } else {
- start_i = (int)FXSYS_floor((FX_FLOAT)src_end);
- end_i = (int)FXSYS_ceil((FX_FLOAT)src_start);
- }
- if (start_i < src_min) {
- start_i = src_min;
- }
- if (end_i >= src_max) {
- end_i = src_max - 1;
- }
- if (start_i > end_i) {
- if (start_i >= src_max) {
- start_i = src_max - 1;
- }
- pixel_weights.m_SrcStart = start_i;
- pixel_weights.m_SrcEnd = start_i;
- continue;
- }
- pixel_weights.m_SrcStart = start_i;
- pixel_weights.m_SrcEnd = end_i;
- for (int j = start_i; j <= end_i; j ++) {
- double dest_start = FXSYS_Div((FX_FLOAT)(j) - base, scale);
- double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale);
- if (dest_start > dest_end) {
- double temp = dest_start;
- dest_start = dest_end;
- dest_end = temp;
- }
- double area_start = dest_start > (FX_FLOAT)(dest_pixel) ? dest_start : (FX_FLOAT)(dest_pixel);
- double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) ? (FX_FLOAT)(dest_pixel + 1) : dest_end;
- double weight = area_start >= area_end ? 0.0f : area_end - area_start;
- if (weight == 0 && j == end_i) {
- pixel_weights.m_SrcEnd --;
- break;
- }
- pixel_weights.m_Weights[j - start_i] = FXSYS_round((FX_FLOAT)(weight * 65536));
- }
- }
-}
-CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap, FXDIB_Format dest_format,
- int dest_width, int dest_height, const FX_RECT& clip_rect,
- const CFX_DIBSource* pSrcBitmap, int flags)
-{
- m_State = 0;
- m_DestFormat = dest_format;
- m_DestBpp = dest_format & 0xff;
- m_SrcBpp = pSrcBitmap->GetFormat() & 0xff;
- m_bHasAlpha = pSrcBitmap->GetFormat() & 0x200;
- m_pSrcPalette = pSrcBitmap->GetPalette();
- m_pDestBitmap = pDestBitmap;
- m_DestWidth = dest_width;
- m_DestHeight = dest_height;
- m_pInterBuf = NULL;
- m_pExtraAlphaBuf = NULL;
- m_pDestMaskScanline = NULL;
- m_DestClip = clip_rect;
- FX_DWORD size = clip_rect.Width();
- if (size && m_DestBpp > (int)(INT_MAX / size)) {
- return;
- }
- size *= m_DestBpp;
- if (size > INT_MAX - 31) {
- return;
- }
- size += 31;
- size = size / 32 * 4;
- m_pDestScanline = FX_AllocNL(FX_BYTE, size);
- if (m_pDestScanline == NULL) {
- return;
- }
- FXSYS_memset32(m_pDestScanline, 0, sizeof(FX_BYTE) * size);
- if (dest_format == FXDIB_Rgb32) {
- FXSYS_memset8(m_pDestScanline, 255, size);
- }
- m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4;
- m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4;
- m_pInterBuf = NULL;
- m_pSource = pSrcBitmap;
- m_SrcWidth = pSrcBitmap->GetWidth();
- m_SrcHeight = pSrcBitmap->GetHeight();
- m_SrcPitch = (m_SrcWidth * m_SrcBpp + 31) / 32 * 4;
- if ((flags & FXDIB_NOSMOOTH) == 0) {
- FX_BOOL bInterpol = flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL;
- if (!bInterpol && FXSYS_abs(dest_width) != 0 && FXSYS_abs(dest_height) < m_SrcWidth * m_SrcHeight * 8 / FXSYS_abs(dest_width)) {
- flags = FXDIB_INTERPOL;
- }
- m_Flags = flags;
- } else {
- m_Flags = FXDIB_NOSMOOTH;
- if (flags & FXDIB_DOWNSAMPLE) {
- m_Flags |= FXDIB_DOWNSAMPLE;
- }
- }
- double scale_x = FXSYS_Div((FX_FLOAT)(m_SrcWidth), (FX_FLOAT)(m_DestWidth));
- double scale_y = FXSYS_Div((FX_FLOAT)(m_SrcHeight), (FX_FLOAT)(m_DestHeight));
- double base_x = m_DestWidth > 0 ? 0.0f : (FX_FLOAT)(m_DestWidth);
- double base_y = m_DestHeight > 0 ? 0.0f : (FX_FLOAT)(m_DestHeight);
- double src_left = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.left) + base_x);
- double src_right = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.right) + base_x);
- double src_top = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.top) + base_y);
- double src_bottom = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.bottom) + base_y);
- if (src_left > src_right) {
- double temp = src_left;
- src_left = src_right;
- src_right = temp;
- }
- if (src_top > src_bottom) {
- double temp = src_top;
- src_top = src_bottom;
- src_bottom = temp;
- }
- m_SrcClip.left = (int)FXSYS_floor((FX_FLOAT)src_left);
- m_SrcClip.right = (int)FXSYS_ceil((FX_FLOAT)src_right);
- m_SrcClip.top = (int)FXSYS_floor((FX_FLOAT)src_top);
- m_SrcClip.bottom = (int)FXSYS_ceil((FX_FLOAT)src_bottom);
- FX_RECT src_rect(0, 0, m_SrcWidth, m_SrcHeight);
- m_SrcClip.Intersect(src_rect);
- if (m_SrcBpp == 1) {
- if (m_DestBpp == 8) {
- m_TransMethod = 1;
- } else {
- m_TransMethod = 2;
- }
- } else if (m_SrcBpp == 8) {
- if (m_DestBpp == 8) {
- if (!m_bHasAlpha) {
- m_TransMethod = 3;
- } else {
- m_TransMethod = 4;
- }
- } else {
- if (!m_bHasAlpha) {
- m_TransMethod = 5;
- } else {
- m_TransMethod = 6;
- }
- }
- } else {
- if (!m_bHasAlpha) {
- m_TransMethod = 7;
- } else {
- m_TransMethod = 8;
- }
- }
-}
-FX_BOOL CStretchEngine::Continue(IFX_Pause* pPause)
-{
- while (m_State == 1) {
- if (ContinueStretchHorz(pPause)) {
- return TRUE;
- }
- m_State = 2;
- StretchVert();
- }
- return FALSE;
-}
-CStretchEngine::~CStretchEngine()
-{
- if (m_pDestScanline) {
- FX_Free(m_pDestScanline);
- }
- if (m_pInterBuf) {
- FX_Free(m_pInterBuf);
- }
- if (m_pExtraAlphaBuf) {
- FX_Free(m_pExtraAlphaBuf);
- }
- if (m_pDestMaskScanline) {
- FX_Free(m_pDestMaskScanline);
- }
-}
-FX_BOOL CStretchEngine::StartStretchHorz()
-{
- if (m_DestWidth == 0 || m_pDestScanline == NULL || m_SrcClip.Height() > (int)((1U << 29) / m_InterPitch) || m_SrcClip.Height() == 0) {
- return FALSE;
- }
-#ifndef _FPDFAPI_MINI_
- m_pInterBuf = FX_AllocNL(unsigned char, m_SrcClip.Height() * m_InterPitch);
-#else
- m_pInterBuf = FX_Alloc(unsigned char, m_SrcClip.Height() * m_InterPitch);
-#endif
- if (m_pInterBuf == NULL) {
- return FALSE;
- }
- if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) {
- m_pExtraAlphaBuf = FX_Alloc(unsigned char, m_SrcClip.Height() * m_ExtraMaskPitch);
- if (!m_pExtraAlphaBuf) {
- return FALSE;
- }
- FX_DWORD size = (m_DestClip.Width() * 8 + 31) / 32 * 4;
- m_pDestMaskScanline = FX_AllocNL(unsigned char, size);
- if (!m_pDestMaskScanline) {
- return FALSE;
- }
- }
- m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, m_SrcWidth, m_SrcClip.left, m_SrcClip.right, m_Flags);
- if (m_WeightTable.m_pWeightTables == NULL) {
- return FALSE;
- }
- m_CurRow = m_SrcClip.top;
- m_State = 1;
- return TRUE;
-}
-#define FX_STRECH_PAUSE_ROWS 10
-FX_BOOL CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause)
-{
- if (!m_DestWidth) {
- return 0;
- }
- if (m_pSource->SkipToScanline(m_CurRow, pPause)) {
- return TRUE;
- }
- int Bpp = m_DestBpp / 8;
- int rows_to_go = FX_STRECH_PAUSE_ROWS;
- for (; m_CurRow < m_SrcClip.bottom; m_CurRow ++) {
- if (rows_to_go == 0) {
- if (pPause && pPause->NeedToPauseNow()) {
- return TRUE;
- } else {
- rows_to_go = FX_STRECH_PAUSE_ROWS;
- }
- }
- FX_LPCBYTE src_scan = m_pSource->GetScanline(m_CurRow);
- FX_LPBYTE dest_scan = m_pInterBuf + (m_CurRow - m_SrcClip.top) * m_InterPitch;
- FX_LPCBYTE src_scan_mask = NULL;
- FX_LPBYTE dest_scan_mask = NULL;
- if (m_pExtraAlphaBuf) {
- src_scan_mask = m_pSource->m_pAlphaMask->GetScanline(m_CurRow);
- dest_scan_mask = m_pExtraAlphaBuf + (m_CurRow - m_SrcClip.top) * m_ExtraMaskPitch;
- }
- switch (m_TransMethod) {
- case 1:
- case 2: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
- int dest_a = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- if (src_scan[j / 8] & (1 << (7 - j % 8))) {
- dest_a += pixel_weight * 255;
- }
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
- }
- *dest_scan++ = (FX_BYTE)(dest_a >> 16);
- }
- break;
- }
- case 3: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
- int dest_a = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- dest_a += pixel_weight * src_scan[j];
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
- }
- *dest_scan++ = (FX_BYTE)(dest_a >> 16);
- }
- break;
- }
- case 4: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
- int dest_a = 0, dest_r = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- pixel_weight = pixel_weight * src_scan_mask[j] / 255;
- dest_r += pixel_weight * src_scan[j];
- dest_a += pixel_weight;
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_r = dest_r < 0 ? 0 : dest_r > 16711680 ? 16711680 : dest_r;
- dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a;
- }
- *dest_scan++ = (FX_BYTE)(dest_r >> 16);
- *dest_scan_mask++ = (FX_BYTE)((dest_a * 255) >> 16);
- }
- break;
- }
- case 5: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
- int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]];
- if (m_DestFormat == FXDIB_Rgb) {
- dest_r_y += pixel_weight * (FX_BYTE)(argb_cmyk >> 16);
- dest_g_m += pixel_weight * (FX_BYTE)(argb_cmyk >> 8);
- dest_b_c += pixel_weight * (FX_BYTE)argb_cmyk;
- } else {
- dest_b_c += pixel_weight * (FX_BYTE)(argb_cmyk >> 24);
- dest_g_m += pixel_weight * (FX_BYTE)(argb_cmyk >> 16);
- dest_r_y += pixel_weight * (FX_BYTE)(argb_cmyk >> 8);
- }
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
- dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
- dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
- }
- *dest_scan++ = (FX_BYTE)(dest_b_c >> 16);
- *dest_scan++ = (FX_BYTE)(dest_g_m >> 16);
- *dest_scan++ = (FX_BYTE)(dest_r_y >> 16);
- }
- break;
- }
- case 6: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
- int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- pixel_weight = pixel_weight * src_scan_mask[j] / 255;
- unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]];
- if (m_DestFormat == FXDIB_Rgba) {
- dest_r_y += pixel_weight * (FX_BYTE)(argb_cmyk >> 16);
- dest_g_m += pixel_weight * (FX_BYTE)(argb_cmyk >> 8);
- dest_b_c += pixel_weight * (FX_BYTE)argb_cmyk;
- } else {
- dest_b_c += pixel_weight * (FX_BYTE)(argb_cmyk >> 24);
- dest_g_m += pixel_weight * (FX_BYTE)(argb_cmyk >> 16);
- dest_r_y += pixel_weight * (FX_BYTE)(argb_cmyk >> 8);
- }
- dest_a += pixel_weight;
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_k = dest_k < 0 ? 0 : dest_k > 16711680 ? 16711680 : dest_k;
- dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
- dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
- dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
- dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a;
- }
- *dest_scan++ = (FX_BYTE)(dest_b_c >> 16);
- *dest_scan++ = (FX_BYTE)(dest_g_m >> 16);
- *dest_scan++ = (FX_BYTE)(dest_r_y >> 16);
- *dest_scan_mask++ = (FX_BYTE)((dest_a * 255) >> 16);
- }
- break;
- }
- case 7: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
- int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- FX_LPCBYTE src_pixel = src_scan + j * Bpp;
- dest_b_c += pixel_weight * (*src_pixel++);
- dest_g_m += pixel_weight * (*src_pixel++);
- dest_r_y += pixel_weight * (*src_pixel);
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
- dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
- dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
- }
- *dest_scan++ = (FX_BYTE)((dest_b_c) >> 16);
- *dest_scan++ = (FX_BYTE)((dest_g_m) >> 16);
- *dest_scan++ = (FX_BYTE)((dest_r_y) >> 16);
- dest_scan += Bpp - 3;
- }
- break;
- }
- case 8: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
- int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- FX_LPCBYTE src_pixel = src_scan + j * Bpp;
- if (m_DestFormat == FXDIB_Argb) {
- pixel_weight = pixel_weight * src_pixel[3] / 255;
- } else {
- pixel_weight = pixel_weight * src_scan_mask[j] / 255;
- }
- dest_b_c += pixel_weight * (*src_pixel++);
- dest_g_m += pixel_weight * (*src_pixel++);
- dest_r_y += pixel_weight * (*src_pixel);
- dest_a += pixel_weight;
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
- dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
- dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
- dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a;
- }
- *dest_scan++ = (FX_BYTE)((dest_b_c) >> 16);
- *dest_scan++ = (FX_BYTE)((dest_g_m) >> 16);
- *dest_scan++ = (FX_BYTE)((dest_r_y) >> 16);
- if (m_DestFormat == FXDIB_Argb) {
- *dest_scan = (FX_BYTE)((dest_a * 255) >> 16);
- }
- if (dest_scan_mask) {
- *dest_scan_mask++ = (FX_BYTE)((dest_a * 255) >> 16);
- }
- dest_scan += Bpp - 3;
- }
- break;
- }
- }
- rows_to_go --;
- }
- return FALSE;
-}
-void CStretchEngine::StretchVert()
-{
- if (m_DestHeight == 0) {
- return;
- }
- CWeightTable table;
- table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, m_SrcHeight, m_SrcClip.top, m_SrcClip.bottom, m_Flags);
- if (table.m_pWeightTables == NULL) {
- return;
- }
- int DestBpp = m_DestBpp / 8;
- for (int row = m_DestClip.top; row < m_DestClip.bottom; row ++) {
- unsigned char* dest_scan = m_pDestScanline;
- unsigned char* dest_sacn_mask = m_pDestMaskScanline;
- PixelWeight* pPixelWeights = table.GetPixelWeight(row);
- switch(m_TransMethod) {
- case 1:
- case 2:
- case 3: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp;
- int dest_a = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- dest_a += pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch];
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
- }
- *dest_scan = (FX_BYTE)(dest_a >> 16);
- dest_scan += DestBpp;
- }
- break;
- }
- case 4: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp;
- unsigned char* src_scan_mask = m_pExtraAlphaBuf + (col - m_DestClip.left);
- int dest_a = 0, dest_k = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- dest_k += pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch];
- dest_a += pixel_weight * src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch];
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_k = dest_k < 0 ? 0 : dest_k > 16711680 ? 16711680 : dest_k;
- dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
- }
- *dest_scan = (FX_BYTE)(dest_k >> 16);
- dest_scan += DestBpp;
- *dest_sacn_mask++ = (FX_BYTE)(dest_a >> 16);
- }
- break;
- }
- case 5:
- case 7: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp;
- int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- FX_LPCBYTE src_pixel = src_scan + (j - m_SrcClip.top) * m_InterPitch;
- dest_b_c += pixel_weight * (*src_pixel++);
- dest_g_m += pixel_weight * (*src_pixel++);
- dest_r_y += pixel_weight * (*src_pixel);
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
- dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
- dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
- }
- dest_scan[0] = (FX_BYTE)((dest_b_c) >> 16);
- dest_scan[1] = (FX_BYTE)((dest_g_m) >> 16);
- dest_scan[2] = (FX_BYTE)((dest_r_y) >> 16);
- dest_scan += DestBpp;
- }
- break;
- }
- case 6:
- case 8: {
- for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
- unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp;
- unsigned char* src_scan_mask = NULL;
- if (m_DestFormat != FXDIB_Argb) {
- src_scan_mask = m_pExtraAlphaBuf + (col - m_DestClip.left);
- }
- int dest_a = 0, dest_k = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0;
- for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
- int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
- FX_LPCBYTE src_pixel = src_scan + (j - m_SrcClip.top) * m_InterPitch;
- int mask_v = 255;
- if (src_scan_mask) {
- mask_v = src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch];
- }
- dest_b_c += pixel_weight * (*src_pixel++);
- dest_g_m += pixel_weight * (*src_pixel++);
- dest_r_y += pixel_weight * (*src_pixel);
- if (m_DestFormat == FXDIB_Argb) {
- dest_a += pixel_weight * (*(src_pixel + 1));
- } else {
- dest_a += pixel_weight * mask_v;
- }
- }
- if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
- dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
- dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
- dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
- }
- if (dest_a) {
- int r = ((FX_DWORD)dest_r_y) * 255 / dest_a;
- int g = ((FX_DWORD)dest_g_m) * 255 / dest_a;
- int b = ((FX_DWORD)dest_b_c) * 255 / dest_a;
- dest_scan[0] = b > 255 ? 255 : b < 0 ? 0 : b;
- dest_scan[1] = g > 255 ? 255 : g < 0 ? 0 : g;
- dest_scan[2] = r > 255 ? 255 : r < 0 ? 0 : r;
- }
- if (m_DestFormat == FXDIB_Argb) {
- dest_scan[3] = (FX_BYTE)((dest_a) >> 16);
- } else {
- *dest_sacn_mask = (FX_BYTE)((dest_a) >> 16);
- }
- dest_scan += DestBpp;
- if (dest_sacn_mask) {
- dest_sacn_mask++;
- }
- }
- break;
- }
- }
- m_pDestBitmap->ComposeScanline(row - m_DestClip.top, m_pDestScanline, m_pDestMaskScanline);
- }
-}
-CFX_ImageStretcher::CFX_ImageStretcher()
-{
- m_pScanline = NULL;
- m_pStretchEngine = NULL;
- m_pMaskScanline = NULL;
-}
-CFX_ImageStretcher::~CFX_ImageStretcher()
-{
- if (m_pScanline) {
- FX_Free(m_pScanline);
- }
- if (m_pStretchEngine) {
- delete m_pStretchEngine;
- }
- if (m_pMaskScanline) {
- FX_Free(m_pMaskScanline);
- }
-}
-FXDIB_Format _GetStretchedFormat(const CFX_DIBSource* pSrc)
-{
- FXDIB_Format format = pSrc->GetFormat();
- if (format == FXDIB_1bppMask) {
- format = FXDIB_8bppMask;
- } else if (format == FXDIB_1bppRgb) {
- format = FXDIB_8bppRgb;
- } else if (format == FXDIB_8bppRgb) {
- if (pSrc->GetPalette()) {
- format = FXDIB_Rgb;
- }
- }
- return format;
-}
-FX_BOOL CFX_ImageStretcher::Start(IFX_ScanlineComposer* pDest,
- const CFX_DIBSource* pSource, int dest_width, int dest_height,
- const FX_RECT& rect, FX_DWORD flags)
-{
- m_DestFormat = _GetStretchedFormat(pSource);
- m_DestBPP = m_DestFormat & 0xff;
- m_pDest = pDest;
- m_pSource = pSource;
- m_DestWidth = dest_width;
- m_DestHeight = dest_height;
- m_ClipRect = rect;
- m_Flags = flags;
- if (pSource->GetFormat() == FXDIB_1bppRgb && pSource->GetPalette()) {
- FX_ARGB pal[256];
- int a0, r0, g0, b0, a1, r1, g1, b1;
- ArgbDecode(pSource->GetPaletteEntry(0), a0, r0, g0, b0);
- ArgbDecode(pSource->GetPaletteEntry(1), a1, r1, g1, b1);
- for (int i = 0; i < 256; i ++) {
- int a = a0 + (a1 - a0) * i / 255;
- int r = r0 + (r1 - r0) * i / 255;
- int g = g0 + (g1 - g0) * i / 255;
- int b = b0 + (b1 - b0) * i / 255;
- pal[i] = ArgbEncode(a, r, g, b);
- }
- if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, pal)) {
- return FALSE;
- }
- } else if (pSource->GetFormat() == FXDIB_1bppCmyk && pSource->GetPalette()) {
- FX_CMYK pal[256];
- int c0, m0, y0, k0, c1, m1, y1, k1;
- CmykDecode(pSource->GetPaletteEntry(0), c0, m0, y0, k0);
- CmykDecode(pSource->GetPaletteEntry(1), c1, m1, y1, k1);
- for (int i = 0; i < 256; i ++) {
- int c = c0 + (c1 - c0) * i / 255;
- int m = m0 + (m1 - m0) * i / 255;
- int y = y0 + (y1 - y0) * i / 255;
- int k = k0 + (k1 - k0) * i / 255;
- pal[i] = CmykEncode(c, m, y, k);
- }
- if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, pal)) {
- return FALSE;
- }
- } else if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, NULL)) {
- return FALSE;
- }
- if (flags & FXDIB_DOWNSAMPLE) {
- return StartQuickStretch();
- } else {
- return StartStretch();
- }
-}
-FX_BOOL CFX_ImageStretcher::Continue(IFX_Pause* pPause)
-{
- if (m_Flags & FXDIB_DOWNSAMPLE) {
- return ContinueQuickStretch(pPause);
- } else {
- return ContinueStretch(pPause);
- }
-}
-#ifndef _FPDFAPI_MINI_
-#define MAX_PROGRESSIVE_STRETCH_PIXELS 1000000
-#else
-#define MAX_PROGRESSIVE_STRETCH_PIXELS 100000
-#endif
-FX_BOOL CFX_ImageStretcher::StartStretch()
-{
- m_pStretchEngine = FX_NEW CStretchEngine(m_pDest, m_DestFormat, m_DestWidth, m_DestHeight, m_ClipRect, m_pSource, m_Flags);
- if (!m_pStretchEngine) {
- return FALSE;
- }
- m_pStretchEngine->StartStretchHorz();
- if (m_pSource->GetWidth() * m_pSource->GetHeight() < MAX_PROGRESSIVE_STRETCH_PIXELS) {
- m_pStretchEngine->Continue(NULL);
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause)
-{
- if (m_pStretchEngine == NULL) {
- return FALSE;
- }
- return m_pStretchEngine->Continue(pPause);
-}
-FX_BOOL CFX_ImageStretcher::StartQuickStretch()
-{
-#ifdef _FPDFAPI_MINI_
- m_pSource->SetDownSampleSize(m_DestWidth, m_DestHeight);
-#endif
- m_bFlipX = FALSE;
- m_bFlipY = FALSE;
- if (m_DestWidth < 0) {
- m_bFlipX = TRUE;
- m_DestWidth = -m_DestWidth;
- }
- if (m_DestHeight < 0) {
- m_bFlipY = TRUE;
- m_DestHeight = -m_DestHeight;
- }
- m_LineIndex = 0;
- FX_DWORD size = m_ClipRect.Width();
- if (size && m_DestBPP > (int)(INT_MAX / size)) {
- return FALSE;
- }
- size *= m_DestBPP;
- m_pScanline = FX_Alloc(FX_BYTE, (size / 8 + 3) / 4 * 4);
- if (!m_pScanline) {
- return FALSE;
- }
- if (m_pSource->m_pAlphaMask) {
- m_pMaskScanline = FX_Alloc(FX_BYTE, (m_ClipRect.Width() + 3) / 4 * 4);
- if (!m_pMaskScanline) {
- return FALSE;
- }
- }
- if (m_pSource->GetWidth() * m_pSource->GetHeight() < MAX_PROGRESSIVE_STRETCH_PIXELS) {
- ContinueQuickStretch(NULL);
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause)
-{
- if (m_pScanline == NULL) {
- return FALSE;
- }
- int result_width = m_ClipRect.Width(), result_height = m_ClipRect.Height();
- int src_width = m_pSource->GetWidth(), src_height = m_pSource->GetHeight();
- for (; m_LineIndex < result_height; m_LineIndex ++) {
- int dest_y, src_y;
- if (m_bFlipY) {
- dest_y = result_height - m_LineIndex - 1;
- src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / m_DestHeight;
- } else {
- dest_y = m_LineIndex;
- src_y = (dest_y + m_ClipRect.top) * src_height / m_DestHeight;
- }
- if (src_y >= src_height) {
- src_y = src_height - 1;
- }
- if (src_y < 0) {
- src_y = 0;
- }
- if (m_pSource->SkipToScanline(src_y, pPause)) {
- return TRUE;
- }
- m_pSource->DownSampleScanline(src_y, m_pScanline, m_DestBPP, m_DestWidth, m_bFlipX, m_ClipRect.left, result_width);
- FX_LPBYTE scan_extra_alpha = NULL;
- if (m_pMaskScanline) {
- m_pSource->m_pAlphaMask->DownSampleScanline(src_y, m_pMaskScanline, 1, m_DestWidth, m_bFlipX, m_ClipRect.left, result_width);
- }
- m_pDest->ComposeScanline(dest_y, m_pScanline, m_pMaskScanline);
- }
- return FALSE;
-}
+// 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 "../../../include/fxge/fx_dib.h"
+#include "../../../include/fxge/fx_ge.h"
+#include "dib_int.h"
+#include <limits.h>
+extern int SDP_Table[513];
+void CWeightTable::Calc(int dest_len, int dest_min, int dest_max, int src_len, int src_min, int src_max, int flags)
+{
+ if (m_pWeightTables) {
+ FX_Free(m_pWeightTables);
+ m_pWeightTables = NULL;
+ }
+ double scale, base;
+ scale = FXSYS_Div((FX_FLOAT)(src_len), (FX_FLOAT)(dest_len));
+ if (dest_len < 0) {
+ base = (FX_FLOAT)(src_len);
+ } else {
+ base = 0;
+ }
+ int ext_size = flags & FXDIB_BICUBIC_INTERPOL ? 3 : 1;
+ m_ItemSize = sizeof(int) * 2 + (int)(sizeof(int) * (FXSYS_ceil(FXSYS_fabs((FX_FLOAT)scale)) + ext_size));
+ m_DestMin = dest_min;
+ if ((dest_max - dest_min) > (int)((1U << 30) - 4) / m_ItemSize) {
+ return;
+ }
+ m_pWeightTables = FX_AllocNL(FX_BYTE, (dest_max - dest_min) * m_ItemSize + 4);
+ if (m_pWeightTables == NULL) {
+ return;
+ }
+ FXSYS_memset32(m_pWeightTables, 0, sizeof(FX_BYTE) * ((dest_max - dest_min)*m_ItemSize + 4));
+ if ((flags & FXDIB_NOSMOOTH) != 0 || FXSYS_fabs((FX_FLOAT)scale) < 1.0f) {
+ for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {
+ PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
+ double src_pos = dest_pixel * scale + scale / 2 + base;
+ if (flags & FXDIB_INTERPOL) {
+ pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2);
+ pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2);
+ if (pixel_weights.m_SrcStart < src_min) {
+ pixel_weights.m_SrcStart = src_min;
+ }
+ if (pixel_weights.m_SrcEnd >= src_max) {
+ pixel_weights.m_SrcEnd = src_max - 1;
+ }
+ if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
+ pixel_weights.m_Weights[0] = 65536;
+ } else {
+ pixel_weights.m_Weights[1] = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 65536);
+ pixel_weights.m_Weights[0] = 65536 - pixel_weights.m_Weights[1];
+ }
+ } else if (flags & FXDIB_BICUBIC_INTERPOL) {
+ pixel_weights.m_SrcStart = (int)FXSYS_floor((FX_FLOAT)src_pos - 1.0f / 2);
+ pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos + 1.0f / 2);
+ int start = pixel_weights.m_SrcStart - 1;
+ int end = pixel_weights.m_SrcEnd + 1;
+ if (start < src_min) {
+ start = src_min;
+ }
+ if (end >= src_max) {
+ end = src_max - 1;
+ }
+ if (pixel_weights.m_SrcStart < src_min) {
+ src_pos += src_min - pixel_weights.m_SrcStart;
+ pixel_weights.m_SrcStart = src_min;
+ }
+ if (pixel_weights.m_SrcEnd >= src_max) {
+ pixel_weights.m_SrcEnd = src_max - 1;
+ }
+ int weight;
+ weight = FXSYS_round((FX_FLOAT)(src_pos - pixel_weights.m_SrcStart - 1.0f / 2) * 256);
+ if (start == end) {
+ pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
+ } else if ((start == pixel_weights.m_SrcStart && (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd ||
+ end == pixel_weights.m_SrcEnd) && start < end) || (start < pixel_weights.m_SrcStart && pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd && end == pixel_weights.m_SrcEnd)) {
+ if (start < pixel_weights.m_SrcStart) {
+ pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8;
+ pixel_weights.m_Weights[1] = (SDP_Table[weight] + SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
+ } else {
+ if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
+ pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight] + SDP_Table[256 - weight]) << 8;
+ pixel_weights.m_Weights[1] = SDP_Table[512 - weight] << 8;
+ } else {
+ pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8;
+ pixel_weights.m_Weights[1] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
+ }
+ }
+ if (pixel_weights.m_SrcStart == pixel_weights.m_SrcEnd) {
+ pixel_weights.m_SrcEnd = end;
+ }
+ if (start < pixel_weights.m_SrcStart) {
+ pixel_weights.m_SrcStart = start;
+ }
+ } else if (start == pixel_weights.m_SrcStart &&
+ start < pixel_weights.m_SrcEnd &&
+ pixel_weights.m_SrcEnd < end) {
+ pixel_weights.m_Weights[0] = (SDP_Table[256 + weight] + SDP_Table[weight]) << 8;
+ pixel_weights.m_Weights[1] = SDP_Table[256 - weight] << 8;
+ pixel_weights.m_Weights[2] = SDP_Table[512 - weight] << 8;
+ pixel_weights.m_SrcEnd = end;
+ } else if (start < pixel_weights.m_SrcStart &&
+ pixel_weights.m_SrcStart < pixel_weights.m_SrcEnd &&
+ pixel_weights.m_SrcEnd == end) {
+ pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8;
+ pixel_weights.m_Weights[1] = SDP_Table[weight] << 8;
+ pixel_weights.m_Weights[2] = (SDP_Table[256 - weight] + SDP_Table[512 - weight]) << 8;
+ pixel_weights.m_SrcStart = start;
+ } else {
+ pixel_weights.m_Weights[0] = SDP_Table[256 + weight] << 8;
+ pixel_weights.m_Weights[1] = SDP_Table[weight] << 8;
+ pixel_weights.m_Weights[2] = SDP_Table[256 - weight] << 8;
+ pixel_weights.m_Weights[3] = SDP_Table[512 - weight] << 8;
+ pixel_weights.m_SrcStart = start;
+ pixel_weights.m_SrcEnd = end;
+ }
+ } else {
+ pixel_weights.m_SrcStart = pixel_weights.m_SrcEnd = (int)FXSYS_floor((FX_FLOAT)src_pos);
+ if (pixel_weights.m_SrcStart < src_min) {
+ pixel_weights.m_SrcStart = src_min;
+ }
+ if (pixel_weights.m_SrcEnd >= src_max) {
+ pixel_weights.m_SrcEnd = src_max - 1;
+ }
+ pixel_weights.m_Weights[0] = 65536;
+ }
+ }
+ return;
+ }
+ for (int dest_pixel = dest_min; dest_pixel < dest_max; dest_pixel ++) {
+ PixelWeight& pixel_weights = *GetPixelWeight(dest_pixel);
+ double src_start = dest_pixel * scale + base;
+ double src_end = src_start + scale;
+ int start_i, end_i;
+ if (src_start < src_end) {
+ start_i = (int)FXSYS_floor((FX_FLOAT)src_start);
+ end_i = (int)FXSYS_ceil((FX_FLOAT)src_end);
+ } else {
+ start_i = (int)FXSYS_floor((FX_FLOAT)src_end);
+ end_i = (int)FXSYS_ceil((FX_FLOAT)src_start);
+ }
+ if (start_i < src_min) {
+ start_i = src_min;
+ }
+ if (end_i >= src_max) {
+ end_i = src_max - 1;
+ }
+ if (start_i > end_i) {
+ if (start_i >= src_max) {
+ start_i = src_max - 1;
+ }
+ pixel_weights.m_SrcStart = start_i;
+ pixel_weights.m_SrcEnd = start_i;
+ continue;
+ }
+ pixel_weights.m_SrcStart = start_i;
+ pixel_weights.m_SrcEnd = end_i;
+ for (int j = start_i; j <= end_i; j ++) {
+ double dest_start = FXSYS_Div((FX_FLOAT)(j) - base, scale);
+ double dest_end = FXSYS_Div((FX_FLOAT)(j + 1) - base, scale);
+ if (dest_start > dest_end) {
+ double temp = dest_start;
+ dest_start = dest_end;
+ dest_end = temp;
+ }
+ double area_start = dest_start > (FX_FLOAT)(dest_pixel) ? dest_start : (FX_FLOAT)(dest_pixel);
+ double area_end = dest_end > (FX_FLOAT)(dest_pixel + 1) ? (FX_FLOAT)(dest_pixel + 1) : dest_end;
+ double weight = area_start >= area_end ? 0.0f : area_end - area_start;
+ if (weight == 0 && j == end_i) {
+ pixel_weights.m_SrcEnd --;
+ break;
+ }
+ pixel_weights.m_Weights[j - start_i] = FXSYS_round((FX_FLOAT)(weight * 65536));
+ }
+ }
+}
+CStretchEngine::CStretchEngine(IFX_ScanlineComposer* pDestBitmap, FXDIB_Format dest_format,
+ int dest_width, int dest_height, const FX_RECT& clip_rect,
+ const CFX_DIBSource* pSrcBitmap, int flags)
+{
+ m_State = 0;
+ m_DestFormat = dest_format;
+ m_DestBpp = dest_format & 0xff;
+ m_SrcBpp = pSrcBitmap->GetFormat() & 0xff;
+ m_bHasAlpha = pSrcBitmap->GetFormat() & 0x200;
+ m_pSrcPalette = pSrcBitmap->GetPalette();
+ m_pDestBitmap = pDestBitmap;
+ m_DestWidth = dest_width;
+ m_DestHeight = dest_height;
+ m_pInterBuf = NULL;
+ m_pExtraAlphaBuf = NULL;
+ m_pDestMaskScanline = NULL;
+ m_DestClip = clip_rect;
+ FX_DWORD size = clip_rect.Width();
+ if (size && m_DestBpp > (int)(INT_MAX / size)) {
+ return;
+ }
+ size *= m_DestBpp;
+ if (size > INT_MAX - 31) {
+ return;
+ }
+ size += 31;
+ size = size / 32 * 4;
+ m_pDestScanline = FX_AllocNL(FX_BYTE, size);
+ if (m_pDestScanline == NULL) {
+ return;
+ }
+ FXSYS_memset32(m_pDestScanline, 0, sizeof(FX_BYTE) * size);
+ if (dest_format == FXDIB_Rgb32) {
+ FXSYS_memset8(m_pDestScanline, 255, size);
+ }
+ m_InterPitch = (m_DestClip.Width() * m_DestBpp + 31) / 32 * 4;
+ m_ExtraMaskPitch = (m_DestClip.Width() * 8 + 31) / 32 * 4;
+ m_pInterBuf = NULL;
+ m_pSource = pSrcBitmap;
+ m_SrcWidth = pSrcBitmap->GetWidth();
+ m_SrcHeight = pSrcBitmap->GetHeight();
+ m_SrcPitch = (m_SrcWidth * m_SrcBpp + 31) / 32 * 4;
+ if ((flags & FXDIB_NOSMOOTH) == 0) {
+ FX_BOOL bInterpol = flags & FXDIB_INTERPOL || flags & FXDIB_BICUBIC_INTERPOL;
+ if (!bInterpol && FXSYS_abs(dest_width) != 0 && FXSYS_abs(dest_height) < m_SrcWidth * m_SrcHeight * 8 / FXSYS_abs(dest_width)) {
+ flags = FXDIB_INTERPOL;
+ }
+ m_Flags = flags;
+ } else {
+ m_Flags = FXDIB_NOSMOOTH;
+ if (flags & FXDIB_DOWNSAMPLE) {
+ m_Flags |= FXDIB_DOWNSAMPLE;
+ }
+ }
+ double scale_x = FXSYS_Div((FX_FLOAT)(m_SrcWidth), (FX_FLOAT)(m_DestWidth));
+ double scale_y = FXSYS_Div((FX_FLOAT)(m_SrcHeight), (FX_FLOAT)(m_DestHeight));
+ double base_x = m_DestWidth > 0 ? 0.0f : (FX_FLOAT)(m_DestWidth);
+ double base_y = m_DestHeight > 0 ? 0.0f : (FX_FLOAT)(m_DestHeight);
+ double src_left = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.left) + base_x);
+ double src_right = FXSYS_Mul(scale_x, (FX_FLOAT)(clip_rect.right) + base_x);
+ double src_top = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.top) + base_y);
+ double src_bottom = FXSYS_Mul(scale_y, (FX_FLOAT)(clip_rect.bottom) + base_y);
+ if (src_left > src_right) {
+ double temp = src_left;
+ src_left = src_right;
+ src_right = temp;
+ }
+ if (src_top > src_bottom) {
+ double temp = src_top;
+ src_top = src_bottom;
+ src_bottom = temp;
+ }
+ m_SrcClip.left = (int)FXSYS_floor((FX_FLOAT)src_left);
+ m_SrcClip.right = (int)FXSYS_ceil((FX_FLOAT)src_right);
+ m_SrcClip.top = (int)FXSYS_floor((FX_FLOAT)src_top);
+ m_SrcClip.bottom = (int)FXSYS_ceil((FX_FLOAT)src_bottom);
+ FX_RECT src_rect(0, 0, m_SrcWidth, m_SrcHeight);
+ m_SrcClip.Intersect(src_rect);
+ if (m_SrcBpp == 1) {
+ if (m_DestBpp == 8) {
+ m_TransMethod = 1;
+ } else {
+ m_TransMethod = 2;
+ }
+ } else if (m_SrcBpp == 8) {
+ if (m_DestBpp == 8) {
+ if (!m_bHasAlpha) {
+ m_TransMethod = 3;
+ } else {
+ m_TransMethod = 4;
+ }
+ } else {
+ if (!m_bHasAlpha) {
+ m_TransMethod = 5;
+ } else {
+ m_TransMethod = 6;
+ }
+ }
+ } else {
+ if (!m_bHasAlpha) {
+ m_TransMethod = 7;
+ } else {
+ m_TransMethod = 8;
+ }
+ }
+}
+FX_BOOL CStretchEngine::Continue(IFX_Pause* pPause)
+{
+ while (m_State == 1) {
+ if (ContinueStretchHorz(pPause)) {
+ return TRUE;
+ }
+ m_State = 2;
+ StretchVert();
+ }
+ return FALSE;
+}
+CStretchEngine::~CStretchEngine()
+{
+ if (m_pDestScanline) {
+ FX_Free(m_pDestScanline);
+ }
+ if (m_pInterBuf) {
+ FX_Free(m_pInterBuf);
+ }
+ if (m_pExtraAlphaBuf) {
+ FX_Free(m_pExtraAlphaBuf);
+ }
+ if (m_pDestMaskScanline) {
+ FX_Free(m_pDestMaskScanline);
+ }
+}
+FX_BOOL CStretchEngine::StartStretchHorz()
+{
+ if (m_DestWidth == 0 || m_pDestScanline == NULL || m_SrcClip.Height() > (int)((1U << 29) / m_InterPitch) || m_SrcClip.Height() == 0) {
+ return FALSE;
+ }
+#ifndef _FPDFAPI_MINI_
+ m_pInterBuf = FX_AllocNL(unsigned char, m_SrcClip.Height() * m_InterPitch);
+#else
+ m_pInterBuf = FX_Alloc(unsigned char, m_SrcClip.Height() * m_InterPitch);
+#endif
+ if (m_pInterBuf == NULL) {
+ return FALSE;
+ }
+ if (m_pSource && m_bHasAlpha && m_pSource->m_pAlphaMask) {
+ m_pExtraAlphaBuf = FX_Alloc(unsigned char, m_SrcClip.Height() * m_ExtraMaskPitch);
+ if (!m_pExtraAlphaBuf) {
+ return FALSE;
+ }
+ FX_DWORD size = (m_DestClip.Width() * 8 + 31) / 32 * 4;
+ m_pDestMaskScanline = FX_AllocNL(unsigned char, size);
+ if (!m_pDestMaskScanline) {
+ return FALSE;
+ }
+ }
+ m_WeightTable.Calc(m_DestWidth, m_DestClip.left, m_DestClip.right, m_SrcWidth, m_SrcClip.left, m_SrcClip.right, m_Flags);
+ if (m_WeightTable.m_pWeightTables == NULL) {
+ return FALSE;
+ }
+ m_CurRow = m_SrcClip.top;
+ m_State = 1;
+ return TRUE;
+}
+#define FX_STRECH_PAUSE_ROWS 10
+FX_BOOL CStretchEngine::ContinueStretchHorz(IFX_Pause* pPause)
+{
+ if (!m_DestWidth) {
+ return 0;
+ }
+ if (m_pSource->SkipToScanline(m_CurRow, pPause)) {
+ return TRUE;
+ }
+ int Bpp = m_DestBpp / 8;
+ int rows_to_go = FX_STRECH_PAUSE_ROWS;
+ for (; m_CurRow < m_SrcClip.bottom; m_CurRow ++) {
+ if (rows_to_go == 0) {
+ if (pPause && pPause->NeedToPauseNow()) {
+ return TRUE;
+ } else {
+ rows_to_go = FX_STRECH_PAUSE_ROWS;
+ }
+ }
+ FX_LPCBYTE src_scan = m_pSource->GetScanline(m_CurRow);
+ FX_LPBYTE dest_scan = m_pInterBuf + (m_CurRow - m_SrcClip.top) * m_InterPitch;
+ FX_LPCBYTE src_scan_mask = NULL;
+ FX_LPBYTE dest_scan_mask = NULL;
+ if (m_pExtraAlphaBuf) {
+ src_scan_mask = m_pSource->m_pAlphaMask->GetScanline(m_CurRow);
+ dest_scan_mask = m_pExtraAlphaBuf + (m_CurRow - m_SrcClip.top) * m_ExtraMaskPitch;
+ }
+ switch (m_TransMethod) {
+ case 1:
+ case 2: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
+ int dest_a = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ if (src_scan[j / 8] & (1 << (7 - j % 8))) {
+ dest_a += pixel_weight * 255;
+ }
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
+ }
+ *dest_scan++ = (FX_BYTE)(dest_a >> 16);
+ }
+ break;
+ }
+ case 3: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
+ int dest_a = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ dest_a += pixel_weight * src_scan[j];
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
+ }
+ *dest_scan++ = (FX_BYTE)(dest_a >> 16);
+ }
+ break;
+ }
+ case 4: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
+ int dest_a = 0, dest_r = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ pixel_weight = pixel_weight * src_scan_mask[j] / 255;
+ dest_r += pixel_weight * src_scan[j];
+ dest_a += pixel_weight;
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_r = dest_r < 0 ? 0 : dest_r > 16711680 ? 16711680 : dest_r;
+ dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a;
+ }
+ *dest_scan++ = (FX_BYTE)(dest_r >> 16);
+ *dest_scan_mask++ = (FX_BYTE)((dest_a * 255) >> 16);
+ }
+ break;
+ }
+ case 5: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
+ int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]];
+ if (m_DestFormat == FXDIB_Rgb) {
+ dest_r_y += pixel_weight * (FX_BYTE)(argb_cmyk >> 16);
+ dest_g_m += pixel_weight * (FX_BYTE)(argb_cmyk >> 8);
+ dest_b_c += pixel_weight * (FX_BYTE)argb_cmyk;
+ } else {
+ dest_b_c += pixel_weight * (FX_BYTE)(argb_cmyk >> 24);
+ dest_g_m += pixel_weight * (FX_BYTE)(argb_cmyk >> 16);
+ dest_r_y += pixel_weight * (FX_BYTE)(argb_cmyk >> 8);
+ }
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
+ dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
+ dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
+ }
+ *dest_scan++ = (FX_BYTE)(dest_b_c >> 16);
+ *dest_scan++ = (FX_BYTE)(dest_g_m >> 16);
+ *dest_scan++ = (FX_BYTE)(dest_r_y >> 16);
+ }
+ break;
+ }
+ case 6: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
+ int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ pixel_weight = pixel_weight * src_scan_mask[j] / 255;
+ unsigned long argb_cmyk = m_pSrcPalette[src_scan[j]];
+ if (m_DestFormat == FXDIB_Rgba) {
+ dest_r_y += pixel_weight * (FX_BYTE)(argb_cmyk >> 16);
+ dest_g_m += pixel_weight * (FX_BYTE)(argb_cmyk >> 8);
+ dest_b_c += pixel_weight * (FX_BYTE)argb_cmyk;
+ } else {
+ dest_b_c += pixel_weight * (FX_BYTE)(argb_cmyk >> 24);
+ dest_g_m += pixel_weight * (FX_BYTE)(argb_cmyk >> 16);
+ dest_r_y += pixel_weight * (FX_BYTE)(argb_cmyk >> 8);
+ }
+ dest_a += pixel_weight;
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_k = dest_k < 0 ? 0 : dest_k > 16711680 ? 16711680 : dest_k;
+ dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
+ dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
+ dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
+ dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a;
+ }
+ *dest_scan++ = (FX_BYTE)(dest_b_c >> 16);
+ *dest_scan++ = (FX_BYTE)(dest_g_m >> 16);
+ *dest_scan++ = (FX_BYTE)(dest_r_y >> 16);
+ *dest_scan_mask++ = (FX_BYTE)((dest_a * 255) >> 16);
+ }
+ break;
+ }
+ case 7: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
+ int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ FX_LPCBYTE src_pixel = src_scan + j * Bpp;
+ dest_b_c += pixel_weight * (*src_pixel++);
+ dest_g_m += pixel_weight * (*src_pixel++);
+ dest_r_y += pixel_weight * (*src_pixel);
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
+ dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
+ dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
+ }
+ *dest_scan++ = (FX_BYTE)((dest_b_c) >> 16);
+ *dest_scan++ = (FX_BYTE)((dest_g_m) >> 16);
+ *dest_scan++ = (FX_BYTE)((dest_r_y) >> 16);
+ dest_scan += Bpp - 3;
+ }
+ break;
+ }
+ case 8: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ PixelWeight* pPixelWeights = m_WeightTable.GetPixelWeight(col);
+ int dest_a = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ FX_LPCBYTE src_pixel = src_scan + j * Bpp;
+ if (m_DestFormat == FXDIB_Argb) {
+ pixel_weight = pixel_weight * src_pixel[3] / 255;
+ } else {
+ pixel_weight = pixel_weight * src_scan_mask[j] / 255;
+ }
+ dest_b_c += pixel_weight * (*src_pixel++);
+ dest_g_m += pixel_weight * (*src_pixel++);
+ dest_r_y += pixel_weight * (*src_pixel);
+ dest_a += pixel_weight;
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
+ dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
+ dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
+ dest_a = dest_a < 0 ? 0 : dest_a > 65536 ? 65536 : dest_a;
+ }
+ *dest_scan++ = (FX_BYTE)((dest_b_c) >> 16);
+ *dest_scan++ = (FX_BYTE)((dest_g_m) >> 16);
+ *dest_scan++ = (FX_BYTE)((dest_r_y) >> 16);
+ if (m_DestFormat == FXDIB_Argb) {
+ *dest_scan = (FX_BYTE)((dest_a * 255) >> 16);
+ }
+ if (dest_scan_mask) {
+ *dest_scan_mask++ = (FX_BYTE)((dest_a * 255) >> 16);
+ }
+ dest_scan += Bpp - 3;
+ }
+ break;
+ }
+ }
+ rows_to_go --;
+ }
+ return FALSE;
+}
+void CStretchEngine::StretchVert()
+{
+ if (m_DestHeight == 0) {
+ return;
+ }
+ CWeightTable table;
+ table.Calc(m_DestHeight, m_DestClip.top, m_DestClip.bottom, m_SrcHeight, m_SrcClip.top, m_SrcClip.bottom, m_Flags);
+ if (table.m_pWeightTables == NULL) {
+ return;
+ }
+ int DestBpp = m_DestBpp / 8;
+ for (int row = m_DestClip.top; row < m_DestClip.bottom; row ++) {
+ unsigned char* dest_scan = m_pDestScanline;
+ unsigned char* dest_sacn_mask = m_pDestMaskScanline;
+ PixelWeight* pPixelWeights = table.GetPixelWeight(row);
+ switch(m_TransMethod) {
+ case 1:
+ case 2:
+ case 3: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp;
+ int dest_a = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ dest_a += pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch];
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
+ }
+ *dest_scan = (FX_BYTE)(dest_a >> 16);
+ dest_scan += DestBpp;
+ }
+ break;
+ }
+ case 4: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp;
+ unsigned char* src_scan_mask = m_pExtraAlphaBuf + (col - m_DestClip.left);
+ int dest_a = 0, dest_k = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ dest_k += pixel_weight * src_scan[(j - m_SrcClip.top) * m_InterPitch];
+ dest_a += pixel_weight * src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch];
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_k = dest_k < 0 ? 0 : dest_k > 16711680 ? 16711680 : dest_k;
+ dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
+ }
+ *dest_scan = (FX_BYTE)(dest_k >> 16);
+ dest_scan += DestBpp;
+ *dest_sacn_mask++ = (FX_BYTE)(dest_a >> 16);
+ }
+ break;
+ }
+ case 5:
+ case 7: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp;
+ int dest_r_y = 0, dest_g_m = 0, dest_b_c = 0, dest_k = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ FX_LPCBYTE src_pixel = src_scan + (j - m_SrcClip.top) * m_InterPitch;
+ dest_b_c += pixel_weight * (*src_pixel++);
+ dest_g_m += pixel_weight * (*src_pixel++);
+ dest_r_y += pixel_weight * (*src_pixel);
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
+ dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
+ dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
+ }
+ dest_scan[0] = (FX_BYTE)((dest_b_c) >> 16);
+ dest_scan[1] = (FX_BYTE)((dest_g_m) >> 16);
+ dest_scan[2] = (FX_BYTE)((dest_r_y) >> 16);
+ dest_scan += DestBpp;
+ }
+ break;
+ }
+ case 6:
+ case 8: {
+ for (int col = m_DestClip.left; col < m_DestClip.right; col ++) {
+ unsigned char* src_scan = m_pInterBuf + (col - m_DestClip.left) * DestBpp;
+ unsigned char* src_scan_mask = NULL;
+ if (m_DestFormat != FXDIB_Argb) {
+ src_scan_mask = m_pExtraAlphaBuf + (col - m_DestClip.left);
+ }
+ int dest_a = 0, dest_k = 0, dest_r_y = 0, dest_g_m = 0, dest_b_c = 0;
+ for (int j = pPixelWeights->m_SrcStart; j <= pPixelWeights->m_SrcEnd; j ++) {
+ int pixel_weight = pPixelWeights->m_Weights[j - pPixelWeights->m_SrcStart];
+ FX_LPCBYTE src_pixel = src_scan + (j - m_SrcClip.top) * m_InterPitch;
+ int mask_v = 255;
+ if (src_scan_mask) {
+ mask_v = src_scan_mask[(j - m_SrcClip.top) * m_ExtraMaskPitch];
+ }
+ dest_b_c += pixel_weight * (*src_pixel++);
+ dest_g_m += pixel_weight * (*src_pixel++);
+ dest_r_y += pixel_weight * (*src_pixel);
+ if (m_DestFormat == FXDIB_Argb) {
+ dest_a += pixel_weight * (*(src_pixel + 1));
+ } else {
+ dest_a += pixel_weight * mask_v;
+ }
+ }
+ if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ dest_r_y = dest_r_y < 0 ? 0 : dest_r_y > 16711680 ? 16711680 : dest_r_y;
+ dest_g_m = dest_g_m < 0 ? 0 : dest_g_m > 16711680 ? 16711680 : dest_g_m;
+ dest_b_c = dest_b_c < 0 ? 0 : dest_b_c > 16711680 ? 16711680 : dest_b_c;
+ dest_a = dest_a < 0 ? 0 : dest_a > 16711680 ? 16711680 : dest_a;
+ }
+ if (dest_a) {
+ int r = ((FX_DWORD)dest_r_y) * 255 / dest_a;
+ int g = ((FX_DWORD)dest_g_m) * 255 / dest_a;
+ int b = ((FX_DWORD)dest_b_c) * 255 / dest_a;
+ dest_scan[0] = b > 255 ? 255 : b < 0 ? 0 : b;
+ dest_scan[1] = g > 255 ? 255 : g < 0 ? 0 : g;
+ dest_scan[2] = r > 255 ? 255 : r < 0 ? 0 : r;
+ }
+ if (m_DestFormat == FXDIB_Argb) {
+ dest_scan[3] = (FX_BYTE)((dest_a) >> 16);
+ } else {
+ *dest_sacn_mask = (FX_BYTE)((dest_a) >> 16);
+ }
+ dest_scan += DestBpp;
+ if (dest_sacn_mask) {
+ dest_sacn_mask++;
+ }
+ }
+ break;
+ }
+ }
+ m_pDestBitmap->ComposeScanline(row - m_DestClip.top, m_pDestScanline, m_pDestMaskScanline);
+ }
+}
+CFX_ImageStretcher::CFX_ImageStretcher()
+{
+ m_pScanline = NULL;
+ m_pStretchEngine = NULL;
+ m_pMaskScanline = NULL;
+}
+CFX_ImageStretcher::~CFX_ImageStretcher()
+{
+ if (m_pScanline) {
+ FX_Free(m_pScanline);
+ }
+ if (m_pStretchEngine) {
+ delete m_pStretchEngine;
+ }
+ if (m_pMaskScanline) {
+ FX_Free(m_pMaskScanline);
+ }
+}
+FXDIB_Format _GetStretchedFormat(const CFX_DIBSource* pSrc)
+{
+ FXDIB_Format format = pSrc->GetFormat();
+ if (format == FXDIB_1bppMask) {
+ format = FXDIB_8bppMask;
+ } else if (format == FXDIB_1bppRgb) {
+ format = FXDIB_8bppRgb;
+ } else if (format == FXDIB_8bppRgb) {
+ if (pSrc->GetPalette()) {
+ format = FXDIB_Rgb;
+ }
+ }
+ return format;
+}
+FX_BOOL CFX_ImageStretcher::Start(IFX_ScanlineComposer* pDest,
+ const CFX_DIBSource* pSource, int dest_width, int dest_height,
+ const FX_RECT& rect, FX_DWORD flags)
+{
+ m_DestFormat = _GetStretchedFormat(pSource);
+ m_DestBPP = m_DestFormat & 0xff;
+ m_pDest = pDest;
+ m_pSource = pSource;
+ m_DestWidth = dest_width;
+ m_DestHeight = dest_height;
+ m_ClipRect = rect;
+ m_Flags = flags;
+ if (pSource->GetFormat() == FXDIB_1bppRgb && pSource->GetPalette()) {
+ FX_ARGB pal[256];
+ int a0, r0, g0, b0, a1, r1, g1, b1;
+ ArgbDecode(pSource->GetPaletteEntry(0), a0, r0, g0, b0);
+ ArgbDecode(pSource->GetPaletteEntry(1), a1, r1, g1, b1);
+ for (int i = 0; i < 256; i ++) {
+ int a = a0 + (a1 - a0) * i / 255;
+ int r = r0 + (r1 - r0) * i / 255;
+ int g = g0 + (g1 - g0) * i / 255;
+ int b = b0 + (b1 - b0) * i / 255;
+ pal[i] = ArgbEncode(a, r, g, b);
+ }
+ if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, pal)) {
+ return FALSE;
+ }
+ } else if (pSource->GetFormat() == FXDIB_1bppCmyk && pSource->GetPalette()) {
+ FX_CMYK pal[256];
+ int c0, m0, y0, k0, c1, m1, y1, k1;
+ CmykDecode(pSource->GetPaletteEntry(0), c0, m0, y0, k0);
+ CmykDecode(pSource->GetPaletteEntry(1), c1, m1, y1, k1);
+ for (int i = 0; i < 256; i ++) {
+ int c = c0 + (c1 - c0) * i / 255;
+ int m = m0 + (m1 - m0) * i / 255;
+ int y = y0 + (y1 - y0) * i / 255;
+ int k = k0 + (k1 - k0) * i / 255;
+ pal[i] = CmykEncode(c, m, y, k);
+ }
+ if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, pal)) {
+ return FALSE;
+ }
+ } else if (!pDest->SetInfo(rect.Width(), rect.Height(), m_DestFormat, NULL)) {
+ return FALSE;
+ }
+ if (flags & FXDIB_DOWNSAMPLE) {
+ return StartQuickStretch();
+ } else {
+ return StartStretch();
+ }
+}
+FX_BOOL CFX_ImageStretcher::Continue(IFX_Pause* pPause)
+{
+ if (m_Flags & FXDIB_DOWNSAMPLE) {
+ return ContinueQuickStretch(pPause);
+ } else {
+ return ContinueStretch(pPause);
+ }
+}
+#ifndef _FPDFAPI_MINI_
+#define MAX_PROGRESSIVE_STRETCH_PIXELS 1000000
+#else
+#define MAX_PROGRESSIVE_STRETCH_PIXELS 100000
+#endif
+FX_BOOL CFX_ImageStretcher::StartStretch()
+{
+ m_pStretchEngine = FX_NEW CStretchEngine(m_pDest, m_DestFormat, m_DestWidth, m_DestHeight, m_ClipRect, m_pSource, m_Flags);
+ if (!m_pStretchEngine) {
+ return FALSE;
+ }
+ m_pStretchEngine->StartStretchHorz();
+ if (m_pSource->GetWidth() * m_pSource->GetHeight() < MAX_PROGRESSIVE_STRETCH_PIXELS) {
+ m_pStretchEngine->Continue(NULL);
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_ImageStretcher::ContinueStretch(IFX_Pause* pPause)
+{
+ if (m_pStretchEngine == NULL) {
+ return FALSE;
+ }
+ return m_pStretchEngine->Continue(pPause);
+}
+FX_BOOL CFX_ImageStretcher::StartQuickStretch()
+{
+#ifdef _FPDFAPI_MINI_
+ m_pSource->SetDownSampleSize(m_DestWidth, m_DestHeight);
+#endif
+ m_bFlipX = FALSE;
+ m_bFlipY = FALSE;
+ if (m_DestWidth < 0) {
+ m_bFlipX = TRUE;
+ m_DestWidth = -m_DestWidth;
+ }
+ if (m_DestHeight < 0) {
+ m_bFlipY = TRUE;
+ m_DestHeight = -m_DestHeight;
+ }
+ m_LineIndex = 0;
+ FX_DWORD size = m_ClipRect.Width();
+ if (size && m_DestBPP > (int)(INT_MAX / size)) {
+ return FALSE;
+ }
+ size *= m_DestBPP;
+ m_pScanline = FX_Alloc(FX_BYTE, (size / 8 + 3) / 4 * 4);
+ if (!m_pScanline) {
+ return FALSE;
+ }
+ if (m_pSource->m_pAlphaMask) {
+ m_pMaskScanline = FX_Alloc(FX_BYTE, (m_ClipRect.Width() + 3) / 4 * 4);
+ if (!m_pMaskScanline) {
+ return FALSE;
+ }
+ }
+ if (m_pSource->GetWidth() * m_pSource->GetHeight() < MAX_PROGRESSIVE_STRETCH_PIXELS) {
+ ContinueQuickStretch(NULL);
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_ImageStretcher::ContinueQuickStretch(IFX_Pause* pPause)
+{
+ if (m_pScanline == NULL) {
+ return FALSE;
+ }
+ int result_width = m_ClipRect.Width(), result_height = m_ClipRect.Height();
+ int src_width = m_pSource->GetWidth(), src_height = m_pSource->GetHeight();
+ for (; m_LineIndex < result_height; m_LineIndex ++) {
+ int dest_y, src_y;
+ if (m_bFlipY) {
+ dest_y = result_height - m_LineIndex - 1;
+ src_y = (m_DestHeight - (dest_y + m_ClipRect.top) - 1) * src_height / m_DestHeight;
+ } else {
+ dest_y = m_LineIndex;
+ src_y = (dest_y + m_ClipRect.top) * src_height / m_DestHeight;
+ }
+ if (src_y >= src_height) {
+ src_y = src_height - 1;
+ }
+ if (src_y < 0) {
+ src_y = 0;
+ }
+ if (m_pSource->SkipToScanline(src_y, pPause)) {
+ return TRUE;
+ }
+ m_pSource->DownSampleScanline(src_y, m_pScanline, m_DestBPP, m_DestWidth, m_bFlipX, m_ClipRect.left, result_width);
+ FX_LPBYTE scan_extra_alpha = NULL;
+ if (m_pMaskScanline) {
+ m_pSource->m_pAlphaMask->DownSampleScanline(src_y, m_pMaskScanline, 1, m_DestWidth, m_bFlipX, m_ClipRect.left, result_width);
+ }
+ m_pDest->ComposeScanline(dest_y, m_pScanline, m_pMaskScanline);
+ }
+ return FALSE;
+}
diff --git a/core/src/fxge/dib/fx_dib_main.cpp b/core/src/fxge/dib/fx_dib_main.cpp
index 0953f2d2e5..9b27a13daf 100644
--- a/core/src/fxge/dib/fx_dib_main.cpp
+++ b/core/src/fxge/dib/fx_dib_main.cpp
@@ -1,1734 +1,1734 @@
-// 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 "../../../include/fxge/fx_dib.h"
-#include "../../../include/fxge/fx_ge.h"
-#include "../../../include/fxcodec/fx_codec.h"
-#include "dib_int.h"
-#include <limits.h>
-FX_BOOL ConvertBuffer(FXDIB_Format dest_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD*& pal, void* pIccTransform);
-void CmykDecode(FX_DWORD cmyk, int& c, int& m, int& y, int& k)
-{
- c = FXSYS_GetCValue(cmyk);
- m = FXSYS_GetMValue(cmyk);
- y = FXSYS_GetYValue(cmyk);
- k = FXSYS_GetKValue(cmyk);
-}
-void ArgbDecode(FX_DWORD argb, int& a, int& r, int& g, int& b)
-{
- a = FXARGB_A(argb);
- r = FXARGB_R(argb);
- g = FXARGB_G(argb);
- b = FXARGB_B(argb);
-}
-void ArgbDecode(FX_DWORD argb, int& a, FX_COLORREF& rgb)
-{
- a = FXARGB_A(argb);
- rgb = FXSYS_RGB(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
-}
-FX_DWORD ArgbEncode(int a, FX_COLORREF rgb)
-{
- return FXARGB_MAKE(a, FXSYS_GetRValue(rgb), FXSYS_GetGValue(rgb), FXSYS_GetBValue(rgb));
-}
-CFX_DIBSource::CFX_DIBSource()
-{
- m_bpp = 0;
- m_AlphaFlag = 0;
- m_Width = m_Height = 0;
- m_Pitch = 0;
- m_pPalette = NULL;
- m_pAlphaMask = NULL;
-}
-CFX_DIBSource::~CFX_DIBSource()
-{
- if (m_pPalette) {
- FX_Free(m_pPalette);
- }
- if (m_pAlphaMask) {
- delete m_pAlphaMask;
- }
-}
-CFX_DIBitmap::CFX_DIBitmap()
-{
- m_bExtBuf = FALSE;
- m_pBuffer = NULL;
- m_pPalette = NULL;
-}
-#define _MAX_OOM_LIMIT_ 12000000
-FX_BOOL CFX_DIBitmap::Create(int width, int height, FXDIB_Format format, FX_LPBYTE pBuffer, int pitch)
-{
- m_pBuffer = NULL;
- m_bpp = (FX_BYTE)format;
- m_AlphaFlag = (FX_BYTE)(format >> 8);
- m_Width = m_Height = m_Pitch = 0;
- if (width <= 0 || height <= 0 || pitch < 0) {
- return FALSE;
- }
- if ((INT_MAX - 31) / width < (format & 0xff)) {
- return FALSE;
- }
- if (!pitch) {
- pitch = (width * (format & 0xff) + 31) / 32 * 4;
- }
- if ((1 << 30) / pitch < height) {
- return FALSE;
- }
- if (pBuffer) {
- m_pBuffer = pBuffer;
- m_bExtBuf = TRUE;
- } else {
- int size = pitch * height + 4;
- int oomlimit = _MAX_OOM_LIMIT_;
- if (oomlimit >= 0 && size >= oomlimit) {
- m_pBuffer = FX_AllocNL(FX_BYTE, size);
- } else {
- m_pBuffer = FX_Alloc(FX_BYTE, size);
- }
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- FXSYS_memset32(m_pBuffer, 0, sizeof (FX_BYTE) * size);
- }
- m_Width = width;
- m_Height = height;
- m_Pitch = pitch;
- if (HasAlpha() && format != FXDIB_Argb) {
- FX_BOOL ret = TRUE;
- ret = BuildAlphaMask();
- if (!ret) {
- if (!m_bExtBuf && m_pBuffer) {
- FX_Free(m_pBuffer);
- m_pBuffer = NULL;
- m_Width = m_Height = m_Pitch = 0;
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-FX_BOOL CFX_DIBitmap::Copy(const CFX_DIBSource* pSrc)
-{
- if (m_pBuffer) {
- return FALSE;
- }
- if (!Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat())) {
- return FALSE;
- }
- CopyPalette(pSrc->GetPalette());
- CopyAlphaMask(pSrc->m_pAlphaMask);
- for (int row = 0; row < pSrc->GetHeight(); row ++) {
- FXSYS_memcpy32(m_pBuffer + row * m_Pitch, pSrc->GetScanline(row), m_Pitch);
- }
- return TRUE;
-}
-CFX_DIBitmap::~CFX_DIBitmap()
-{
- if (m_pBuffer && !m_bExtBuf) {
- FX_Free(m_pBuffer);
- }
- m_pBuffer = NULL;
-}
-void CFX_DIBitmap::TakeOver(CFX_DIBitmap* pSrcBitmap)
-{
- if (m_pBuffer && !m_bExtBuf) {
- FX_Free(m_pBuffer);
- }
- if (m_pPalette) {
- FX_Free(m_pPalette);
- }
- if (m_pAlphaMask) {
- delete m_pAlphaMask;
- }
- m_pBuffer = pSrcBitmap->m_pBuffer;
- m_pPalette = pSrcBitmap->m_pPalette;
- m_pAlphaMask = pSrcBitmap->m_pAlphaMask;
- pSrcBitmap->m_pBuffer = NULL;
- pSrcBitmap->m_pPalette = NULL;
- pSrcBitmap->m_pAlphaMask = NULL;
- m_bpp = pSrcBitmap->m_bpp;
- m_bExtBuf = pSrcBitmap->m_bExtBuf;
- m_AlphaFlag = pSrcBitmap->m_AlphaFlag;
- m_Width = pSrcBitmap->m_Width;
- m_Height = pSrcBitmap->m_Height;
- m_Pitch = pSrcBitmap->m_Pitch;
-}
-CFX_DIBitmap* CFX_DIBSource::Clone(const FX_RECT* pClip) const
-{
- FX_RECT rect(0, 0, m_Width, m_Height);
- if (pClip) {
- rect.Intersect(*pClip);
- if (rect.IsEmpty()) {
- return NULL;
- }
- }
- CFX_DIBitmap* pNewBitmap = FX_NEW CFX_DIBitmap;
- if (!pNewBitmap) {
- return NULL;
- }
- if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat())) {
- delete pNewBitmap;
- return NULL;
- }
- pNewBitmap->CopyPalette(m_pPalette);
- pNewBitmap->CopyAlphaMask(m_pAlphaMask, pClip);
- if (GetBPP() == 1 && rect.left % 8 != 0) {
- int left_shift = rect.left % 32;
- int right_shift = 32 - left_shift;
- int dword_count = pNewBitmap->m_Pitch / 4;
- for (int row = rect.top; row < rect.bottom; row ++) {
- FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + rect.left / 32;
- FX_DWORD* dest_scan = (FX_DWORD*)pNewBitmap->GetScanline(row - rect.top);
- for (int i = 0; i < dword_count; i ++) {
- dest_scan[i] = (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift);
- }
- }
- } else {
- int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8;
- if (m_Pitch < (FX_DWORD)copy_len) {
- copy_len = m_Pitch;
- }
- for (int row = rect.top; row < rect.bottom; row ++) {
- FX_LPCBYTE src_scan = GetScanline(row) + rect.left * m_bpp / 8;
- FX_LPBYTE dest_scan = (FX_LPBYTE)pNewBitmap->GetScanline(row - rect.top);
- FXSYS_memcpy32(dest_scan, src_scan, copy_len);
- }
- }
- return pNewBitmap;
-}
-void CFX_DIBSource::BuildPalette()
-{
- if (m_pPalette) {
- return;
- }
- if (GetBPP() == 1) {
- m_pPalette = FX_Alloc(FX_DWORD, 2);
- if (!m_pPalette) {
- return;
- }
- if(IsCmykImage()) {
- m_pPalette[0] = 0xff;
- m_pPalette[1] = 0;
- } else {
- m_pPalette[0] = 0xff000000;
- m_pPalette[1] = 0xffffffff;
- }
- } else if (GetBPP() == 8) {
- m_pPalette = FX_Alloc(FX_DWORD, 256);
- if (!m_pPalette) {
- return;
- }
- if(IsCmykImage()) {
- for (int i = 0; i < 256; i ++) {
- m_pPalette[i] = 0xff - i;
- }
- } else {
- for (int i = 0; i < 256; i ++) {
- m_pPalette[i] = 0xff000000 | (i * 0x10101);
- }
- }
- }
-}
-FX_BOOL CFX_DIBSource::BuildAlphaMask()
-{
- if (m_pAlphaMask) {
- return TRUE;
- }
- m_pAlphaMask = FX_NEW CFX_DIBitmap;
- if (!m_pAlphaMask) {
- return FALSE;
- }
- if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
- delete m_pAlphaMask;
- m_pAlphaMask = NULL;
- return FALSE;
- }
- FXSYS_memset8(m_pAlphaMask->GetBuffer(), 0xff, m_pAlphaMask->GetHeight()*m_pAlphaMask->GetPitch());
- return TRUE;
-}
-FX_DWORD CFX_DIBSource::GetPaletteEntry(int index) const
-{
- ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
- if (m_pPalette) {
- return m_pPalette[index];
- }
- if (IsCmykImage()) {
- if (GetBPP() == 1) {
- return index ? 0 : 0xff;
- }
- return 0xff - index;
- }
- if (GetBPP() == 1) {
- return index ? 0xffffffff : 0xff000000;
- }
- return index * 0x10101 | 0xff000000;
-}
-void CFX_DIBSource::SetPaletteEntry(int index, FX_DWORD color)
-{
- ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
- if (m_pPalette == NULL) {
- BuildPalette();
- }
- m_pPalette[index] = color;
-}
-int CFX_DIBSource::FindPalette(FX_DWORD color) const
-{
- ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
- if (m_pPalette == NULL) {
- if (IsCmykImage()) {
- if (GetBPP() == 1) {
- return ((FX_BYTE)color == 0xff) ? 0 : 1;
- }
- return 0xff - (FX_BYTE)color;
- }
- if (GetBPP() == 1) {
- return ((FX_BYTE)color == 0xff) ? 1 : 0;
- }
- return (FX_BYTE)color;
- }
- int palsize = (1 << GetBPP());
- for (int i = 0; i < palsize; i ++)
- if (m_pPalette[i] == color) {
- return i;
- }
- return -1;
-}
-void CFX_DIBitmap::Clear(FX_DWORD color)
-{
- if (m_pBuffer == NULL) {
- return;
- }
- switch (GetFormat()) {
- case FXDIB_1bppMask:
- FXSYS_memset8(m_pBuffer, (color & 0xff000000) ? 0xff : 0, m_Pitch * m_Height);
- break;
- case FXDIB_1bppRgb: {
- int index = FindPalette(color);
- FXSYS_memset8(m_pBuffer, index ? 0xff : 0, m_Pitch * m_Height);
- break;
- }
- case FXDIB_8bppMask:
- FXSYS_memset8(m_pBuffer, color >> 24, m_Pitch * m_Height);
- break;
- case FXDIB_8bppRgb: {
- int index = FindPalette(color);
- FXSYS_memset8(m_pBuffer, index, m_Pitch * m_Height);
- break;
- }
- case FXDIB_Rgb:
- case FXDIB_Rgba: {
- int a, r, g, b;
- ArgbDecode(color, a, r, g, b);
- if (r == g && g == b) {
- FXSYS_memset8(m_pBuffer, r, m_Pitch * m_Height);
- } else {
- int byte_pos = 0;
- for (int col = 0; col < m_Width; col ++) {
- m_pBuffer[byte_pos++] = b;
- m_pBuffer[byte_pos++] = g;
- m_pBuffer[byte_pos++] = r;
- }
- for (int row = 1; row < m_Height; row ++) {
- FXSYS_memcpy32(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch);
- }
- }
- break;
- }
- case FXDIB_Rgb32:
- case FXDIB_Argb: {
- color = IsCmykImage() ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
- for (int i = 0; i < m_Width; i ++) {
- ((FX_DWORD*)m_pBuffer)[i] = color;
- }
- for (int row = 1; row < m_Height; row ++) {
- FXSYS_memcpy32(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch);
- }
- break;
- }
- default:
- break;
- }
-}
-void CFX_DIBSource::GetOverlapRect(int& dest_left, int& dest_top, int& width, int& height,
- int src_width, int src_height, int& src_left, int& src_top,
- const CFX_ClipRgn* pClipRgn)
-{
- if (width == 0 || height == 0) {
- return;
- }
- ASSERT(width > 0 && height > 0);
- if (dest_left > m_Width || dest_top > m_Height) {
- width = 0;
- height = 0;
- return;
- }
- int x_offset = dest_left - src_left;
- int y_offset = dest_top - src_top;
- FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height);
- FX_RECT src_bound(0, 0, src_width, src_height);
- src_rect.Intersect(src_bound);
- FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset,
- src_rect.right + x_offset, src_rect.bottom + y_offset);
- FX_RECT dest_bound(0, 0, m_Width, m_Height);
- dest_rect.Intersect(dest_bound);
- if (pClipRgn) {
- dest_rect.Intersect(pClipRgn->GetBox());
- }
- dest_left = dest_rect.left;
- dest_top = dest_rect.top;
- src_left = dest_left - x_offset;
- src_top = dest_top - y_offset;
- width = dest_rect.right - dest_rect.left;
- height = dest_rect.bottom - dest_rect.top;
-}
-FX_BOOL CFX_DIBitmap::TransferBitmap(int dest_left, int dest_top, int width, int height,
- const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), src_left, src_top, NULL);
- if (width == 0 || height == 0) {
- return TRUE;
- }
- FXDIB_Format dest_format = GetFormat();
- FXDIB_Format src_format = pSrcBitmap->GetFormat();
- if (dest_format == src_format && pIccTransform == NULL) {
- if (GetBPP() == 1) {
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
- for (int col = 0; col < width; col ++) {
- if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
- dest_scan[(dest_left + col) / 8] |= 1 << (7 - (dest_left + col) % 8);
- } else {
- dest_scan[(dest_left + col) / 8] &= ~(1 << (7 - (dest_left + col) % 8));
- }
- }
- }
- } else {
- int Bpp = GetBPP() / 8;
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp;
- FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
- FXSYS_memcpy32(dest_scan, src_scan, width * Bpp);
- }
- }
- } else {
- if (m_pPalette) {
- return FALSE;
- }
- if (m_bpp == 8) {
- dest_format = FXDIB_8bppMask;
- }
- FX_LPBYTE dest_buf = m_pBuffer + dest_top * m_Pitch + dest_left * GetBPP() / 8;
- FX_DWORD* d_plt = NULL;
- if(!ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height, pSrcBitmap, src_left, src_top, d_plt, pIccTransform)) {
- return FALSE;
- }
- }
- return TRUE;
-}
-#ifndef _FPDFAPI_MINI_
-FX_BOOL CFX_DIBitmap::TransferMask(int dest_left, int dest_top, int width, int height,
- const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top, int alpha_flag, void* pIccTransform)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- ASSERT(HasAlpha() && (m_bpp >= 24));
- ASSERT(pMask->IsAlphaMask());
- if (!HasAlpha() || !pMask->IsAlphaMask() || m_bpp < 24) {
- return FALSE;
- }
- GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, NULL);
- if (width == 0 || height == 0) {
- return TRUE;
- }
- int src_pitch = pMask->GetPitch();
- int src_bpp = pMask->GetBPP();
- int alpha;
- FX_DWORD dst_color;
- if (alpha_flag >> 8) {
- alpha = alpha_flag & 0xff;
- dst_color = FXCMYK_TODIB(color);
- } else {
- alpha = FXARGB_A(color);
- dst_color = FXARGB_TODIB(color);
- }
- FX_LPBYTE color_p = (FX_LPBYTE)&dst_color;
- if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1);
- } else {
- if (alpha_flag >> 8 && !IsCmykImage())
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color),
- color_p[2], color_p[1], color_p[0]);
- else if (!(alpha_flag >> 8) && IsCmykImage()) {
- return FALSE;
- }
- }
- if(!IsCmykImage()) {
- color_p[3] = (FX_BYTE)alpha;
- }
- if (GetFormat() == FXDIB_Argb) {
- for (int row = 0; row < height; row ++) {
- FX_DWORD* dest_pos = (FX_DWORD*)(m_pBuffer + (dest_top + row) * m_Pitch + dest_left * 4);
- FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row);
- if (src_bpp == 1) {
- for (int col = 0; col < width; col ++) {
- int src_bitpos = src_left + col;
- if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) {
- *dest_pos = dst_color;
- } else {
- *dest_pos = 0;
- }
- dest_pos ++;
- }
- } else {
- src_scan += src_left;
- dst_color = FXARGB_TODIB(dst_color);
- dst_color &= 0xffffff;
- for (int col = 0; col < width; col ++) {
- FXARGB_SETDIB(dest_pos++, dst_color | ((alpha * (*src_scan++) / 255) << 24));
- }
- }
- }
- } else {
- int comps = m_bpp / 8;
- for (int row = 0; row < height; row ++) {
- FX_LPBYTE dest_color_pos = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * comps;
- FX_LPBYTE dest_alpha_pos = (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left;
- FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row);
- if (src_bpp == 1) {
- for (int col = 0; col < width; col ++) {
- int src_bitpos = src_left + col;
- if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) {
- FXSYS_memcpy32(dest_color_pos, color_p, comps);
- *dest_alpha_pos = 0xff;
- } else {
- FXSYS_memset32(dest_color_pos, 0, comps);
- *dest_alpha_pos = 0;
- }
- dest_color_pos += comps;
- dest_alpha_pos ++;
- }
- } else {
- src_scan += src_left;
- for (int col = 0; col < width; col ++) {
- FXSYS_memcpy32(dest_color_pos, color_p, comps);
- dest_color_pos += comps;
- *dest_alpha_pos++ = (alpha * (*src_scan++) / 255);
- }
- }
- }
- }
- return TRUE;
-}
-#endif
-void CFX_DIBSource::CopyPalette(const FX_DWORD* pSrc, FX_DWORD size)
-{
- if (pSrc == NULL || GetBPP() > 8) {
- if (m_pPalette) {
- FX_Free(m_pPalette);
- }
- m_pPalette = NULL;
- } else {
- FX_DWORD pal_size = 1 << GetBPP();
- if (m_pPalette == NULL) {
- m_pPalette = FX_Alloc(FX_DWORD, pal_size);
- }
- if (!m_pPalette) {
- return;
- }
- if (pal_size > size) {
- pal_size = size;
- }
- FXSYS_memcpy32(m_pPalette, pSrc, pal_size * sizeof(FX_DWORD));
- }
-}
-void CFX_DIBSource::GetPalette(FX_DWORD* pal, int alpha) const
-{
- ASSERT(GetBPP() <= 8 && !IsCmykImage());
- if (GetBPP() == 1) {
- pal[0] = ((m_pPalette ? m_pPalette[0] : 0xff000000) & 0xffffff) | (alpha << 24);
- pal[1] = ((m_pPalette ? m_pPalette[1] : 0xffffffff) & 0xffffff) | (alpha << 24);
- return;
- }
- if (m_pPalette) {
- for (int i = 0; i < 256; i ++) {
- pal[i] = (m_pPalette[i] & 0x00ffffff) | (alpha << 24);
- }
- } else {
- for (int i = 0; i < 256; i ++) {
- pal[i] = (i * 0x10101) | (alpha << 24);
- }
- }
-}
-CFX_DIBitmap* CFX_DIBSource::GetAlphaMask(const FX_RECT* pClip) const
-{
- ASSERT(GetFormat() == FXDIB_Argb);
- FX_RECT rect(0, 0, m_Width, m_Height);
- if (pClip) {
- rect.Intersect(*pClip);
- if (rect.IsEmpty()) {
- return NULL;
- }
- }
- CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
- if (!pMask) {
- return NULL;
- }
- if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask)) {
- delete pMask;
- return NULL;
- }
- for (int row = rect.top; row < rect.bottom; row ++) {
- FX_LPCBYTE src_scan = GetScanline(row) + rect.left * 4 + 3;
- FX_LPBYTE dest_scan = (FX_LPBYTE)pMask->GetScanline(row - rect.top);
- for (int col = rect.left; col < rect.right; col ++) {
- *dest_scan ++ = *src_scan;
- src_scan += 4;
- }
- }
- return pMask;
-}
-FX_BOOL CFX_DIBSource::CopyAlphaMask(const CFX_DIBSource* pAlphaMask, const FX_RECT* pClip)
-{
- if (!HasAlpha() || GetFormat() == FXDIB_Argb) {
- return FALSE;
- }
- if (pAlphaMask) {
- FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height);
- if (pClip) {
- rect.Intersect(*pClip);
- if (rect.IsEmpty() || rect.Width() != m_Width || rect.Height() != m_Height) {
- return FALSE;
- }
- } else {
- if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Height) {
- return FALSE;
- }
- }
- for (int row = 0; row < m_Height; row ++)
- FXSYS_memcpy32((void*)m_pAlphaMask->GetScanline(row),
- pAlphaMask->GetScanline(row + rect.top) + rect.left, m_pAlphaMask->m_Pitch);
- } else {
- m_pAlphaMask->Clear(0xff000000);
- }
- return TRUE;
-}
-const int g_ChannelOffset[] = {0, 2, 1, 0, 0, 1, 2, 3, 3};
-FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, const CFX_DIBSource* pSrcBitmap, FXDIB_Channel srcChannel)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- CFX_DIBSource* pSrcClone = (CFX_DIBSource*)pSrcBitmap;
- CFX_DIBitmap* pDst = this;
- int destOffset, srcOffset;
- if (srcChannel == FXDIB_Alpha) {
- if (!pSrcBitmap->HasAlpha() && !pSrcBitmap->IsAlphaMask()) {
- return FALSE;
- }
- if (pSrcBitmap->GetBPP() == 1) {
- pSrcClone = pSrcBitmap->CloneConvert(FXDIB_8bppMask);
- if (pSrcClone == NULL) {
- return FALSE;
- }
- }
- if(pSrcBitmap->GetFormat() == FXDIB_Argb) {
- srcOffset = 3;
- } else {
- srcOffset = 0;
- }
- } else {
- if (pSrcBitmap->IsAlphaMask()) {
- return FALSE;
- }
- if (pSrcBitmap->GetBPP() < 24) {
- if (pSrcBitmap->IsCmykImage()) {
- pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x20));
- } else {
- pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x18));
- }
- if (pSrcClone == NULL) {
- return FALSE;
- }
- }
- srcOffset = g_ChannelOffset[srcChannel];
- }
- if (destChannel == FXDIB_Alpha) {
- if (IsAlphaMask()) {
- if(!ConvertFormat(FXDIB_8bppMask)) {
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- return FALSE;
- }
- destOffset = 0;
- } else {
- destOffset = 0;
- if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- return FALSE;
- }
- if (GetFormat() == FXDIB_Argb) {
- destOffset = 3;
- }
- }
- } else {
- if (IsAlphaMask()) {
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- return FALSE;
- }
- if (GetBPP() < 24) {
- if (HasAlpha()) {
- if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- return FALSE;
- }
- } else
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) {
-#else
- if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) {
-#endif
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- return FALSE;
- }
- }
- destOffset = g_ChannelOffset[destChannel];
- }
- if (srcChannel == FXDIB_Alpha && pSrcClone->m_pAlphaMask) {
- CFX_DIBitmap* pAlphaMask = pSrcClone->m_pAlphaMask;
- if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Height) {
- if (pAlphaMask) {
- pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height);
- if (pAlphaMask == NULL) {
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- return FALSE;
- }
- }
- }
- if (pSrcClone != pSrcBitmap) {
- pSrcClone->m_pAlphaMask = NULL;
- delete pSrcClone;
- }
- pSrcClone = pAlphaMask;
- srcOffset = 0;
- } else if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Height) {
- CFX_DIBitmap* pSrcMatched = pSrcClone->StretchTo(m_Width, m_Height);
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- if (pSrcMatched == NULL) {
- return FALSE;
- }
- pSrcClone = pSrcMatched;
- }
- if (destChannel == FXDIB_Alpha && m_pAlphaMask) {
- pDst = m_pAlphaMask;
- destOffset = 0;
- }
- int srcBytes = pSrcClone->GetBPP() / 8;
- int destBytes = pDst->GetBPP() / 8;
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE dest_pos = (FX_LPBYTE)pDst->GetScanline(row) + destOffset;
- FX_LPCBYTE src_pos = pSrcClone->GetScanline(row) + srcOffset;
- for (int col = 0; col < m_Width; col ++) {
- *dest_pos = *src_pos;
- dest_pos += destBytes;
- src_pos += srcBytes;
- }
- }
- if (pSrcClone != pSrcBitmap && pSrcClone != pSrcBitmap->m_pAlphaMask) {
- delete pSrcClone;
- }
- return TRUE;
-}
-FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, int value)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- int destOffset;
- if (destChannel == FXDIB_Alpha) {
- if (IsAlphaMask()) {
- if(!ConvertFormat(FXDIB_8bppMask)) {
- return FALSE;
- }
- destOffset = 0;
- } else {
- destOffset = 0;
- if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
- return FALSE;
- }
- if (GetFormat() == FXDIB_Argb) {
- destOffset = 3;
- }
- }
- } else {
- if (IsAlphaMask()) {
- return FALSE;
- }
- if (GetBPP() < 24) {
- if (HasAlpha()) {
- if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
- return FALSE;
- }
- } else
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) {
- return FALSE;
- }
-#else
- if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) {
- return FALSE;
- }
-#endif
- }
- destOffset = g_ChannelOffset[destChannel];
- }
- int Bpp = GetBPP() / 8;
- if (Bpp == 1) {
- FXSYS_memset8(m_pBuffer, value, m_Height * m_Pitch);
- return TRUE;
- }
- if (destChannel == FXDIB_Alpha && m_pAlphaMask) {
- FXSYS_memset8(m_pAlphaMask->GetBuffer(), value, m_pAlphaMask->GetHeight()*m_pAlphaMask->GetPitch());
- return TRUE;
- }
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch + destOffset;
- for (int col = 0; col < m_Width; col ++) {
- *scan_line = value;
- scan_line += Bpp;
- }
- }
- return TRUE;
-}
-FX_BOOL CFX_DIBitmap::MultiplyAlpha(const CFX_DIBSource* pSrcBitmap)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- ASSERT(pSrcBitmap->IsAlphaMask());
- if (!pSrcBitmap->IsAlphaMask()) {
- return FALSE;
- }
- if (!IsAlphaMask() && !HasAlpha()) {
- return LoadChannel(FXDIB_Alpha, pSrcBitmap, FXDIB_Alpha);
- }
- CFX_DIBitmap* pSrcClone = (CFX_DIBitmap*)pSrcBitmap;
- if (pSrcBitmap->GetWidth() != m_Width || pSrcBitmap->GetHeight() != m_Height) {
- pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height);
- ASSERT(pSrcClone != NULL);
- if (pSrcClone == NULL) {
- return FALSE;
- }
- }
- if (IsAlphaMask()) {
- if(!ConvertFormat(FXDIB_8bppMask)) {
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- return FALSE;
- }
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE dest_scan = m_pBuffer + m_Pitch * row;
- FX_LPBYTE src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row;
- if (pSrcClone->GetBPP() == 1) {
- for (int col = 0; col < m_Width; col ++) {
- if (!((1 << (7 - col % 8)) & src_scan[col / 8])) {
- dest_scan[col] = 0;
- }
- }
- } else {
- for (int col = 0; col < m_Width; col ++) {
- *dest_scan = (*dest_scan) * src_scan[col] / 255;
- dest_scan ++;
- }
- }
- }
- } else {
- if(GetFormat() == FXDIB_Argb) {
- if (pSrcClone->GetBPP() == 1) {
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- return FALSE;
- }
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE dest_scan = m_pBuffer + m_Pitch * row + 3;
- FX_LPBYTE src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row;
- for (int col = 0; col < m_Width; col ++) {
- *dest_scan = (*dest_scan) * src_scan[col] / 255;
- dest_scan += 4;
- }
- }
- } else {
- m_pAlphaMask->MultiplyAlpha(pSrcClone);
- }
- }
- if (pSrcClone != pSrcBitmap) {
- delete pSrcClone;
- }
- return TRUE;
-}
-FX_BOOL CFX_DIBitmap::GetGrayData(void* pIccTransform)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- switch (GetFormat()) {
- case FXDIB_1bppRgb: {
- if (m_pPalette == NULL) {
- return FALSE;
- }
- FX_BYTE gray[2];
- for (int i = 0; i < 2; i ++) {
- int r = (FX_BYTE)(m_pPalette[i] >> 16);
- int g = (FX_BYTE)(m_pPalette[i] >> 8);
- int b = (FX_BYTE)m_pPalette[i];
- gray[i] = (FX_BYTE)FXRGB2GRAY(r, g, b);
- }
- CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
- if (!pMask) {
- return FALSE;
- }
- if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
- delete pMask;
- return FALSE;
- }
- FXSYS_memset8(pMask->GetBuffer(), gray[0], pMask->GetPitch() * m_Height);
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch;
- FX_LPBYTE dest_pos = (FX_LPBYTE)pMask->GetScanline(row);
- for (int col = 0; col < m_Width; col ++) {
- if (src_pos[col / 8] & (1 << (7 - col % 8))) {
- *dest_pos = gray[1];
- }
- dest_pos ++;
- }
- }
- TakeOver(pMask);
- delete pMask;
- break;
- }
- case FXDIB_8bppRgb: {
- if (m_pPalette == NULL) {
- return FALSE;
- }
- FX_BYTE gray[256];
- for (int i = 0; i < 256; i ++) {
- int r = (FX_BYTE)(m_pPalette[i] >> 16);
- int g = (FX_BYTE)(m_pPalette[i] >> 8);
- int b = (FX_BYTE)m_pPalette[i];
- gray[i] = (FX_BYTE)FXRGB2GRAY(r, g, b);
- }
- CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
- if (!pMask) {
- return FALSE;
- }
- if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
- delete pMask;
- return FALSE;
- }
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPitch();
- FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch;
- for (int col = 0; col < m_Width; col ++) {
- *dest_pos ++ = gray[*src_pos ++];
- }
- }
- TakeOver(pMask);
- delete pMask;
- break;
- }
- case FXDIB_Rgb: {
- CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
- if (!pMask) {
- return FALSE;
- }
- if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
- delete pMask;
- return FALSE;
- }
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch;
- FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPitch();
- for (int col = 0; col < m_Width; col ++) {
- *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos);
- src_pos += 3;
- }
- }
- TakeOver(pMask);
- delete pMask;
- break;
- }
- case FXDIB_Rgb32: {
- CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
- if (!pMask) {
- return FALSE;
- }
- if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
- delete pMask;
- return FALSE;
- }
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch;
- FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPitch();
- for (int col = 0; col < m_Width; col ++) {
- *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos);
- src_pos += 4;
- }
- }
- TakeOver(pMask);
- delete pMask;
- break;
- }
- default:
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL CFX_DIBitmap::MultiplyAlpha(int alpha)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- switch (GetFormat()) {
- case FXDIB_1bppMask:
- if (!ConvertFormat(FXDIB_8bppMask)) {
- return FALSE;
- }
- MultiplyAlpha(alpha);
- break;
- case FXDIB_8bppMask: {
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch;
- for (int col = 0; col < m_Width; col ++) {
- scan_line[col] = scan_line[col] * alpha / 255;
- }
- }
- break;
- }
- case FXDIB_Argb: {
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch + 3;
- for (int col = 0; col < m_Width; col ++) {
- *scan_line = (*scan_line) * alpha / 255;
- scan_line += 4;
- }
- }
- break;
- }
- default:
- if (HasAlpha()) {
- m_pAlphaMask->MultiplyAlpha(alpha);
- } else if (IsCmykImage()) {
- if (!ConvertFormat((FXDIB_Format)(GetFormat() | 0x0200))) {
- return FALSE;
- }
- m_pAlphaMask->MultiplyAlpha(alpha);
- } else {
- if (!ConvertFormat(FXDIB_Argb)) {
- return FALSE;
- }
- MultiplyAlpha(alpha);
- }
- break;
- }
- return TRUE;
-}
-#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
-FX_DWORD CFX_DIBitmap::GetPixel(int x, int y) const
-{
- if (m_pBuffer == NULL) {
- return 0;
- }
- FX_LPBYTE pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8;
- switch (GetFormat()) {
- case FXDIB_1bppMask: {
- if ((*pos) & (1 << (7 - x % 8))) {
- return 0xff000000;
- }
- return 0;
- }
- case FXDIB_1bppRgb: {
- if ((*pos) & (1 << (7 - x % 8))) {
- return m_pPalette ? m_pPalette[1] : 0xffffffff;
- } else {
- return m_pPalette ? m_pPalette[0] : 0xff000000;
- }
- break;
- }
- case FXDIB_8bppMask:
- return (*pos) << 24;
- case FXDIB_8bppRgb:
- return m_pPalette ? m_pPalette[*pos] : (0xff000000 | ((*pos) * 0x10101));
- case FXDIB_Rgb:
- case FXDIB_Rgba:
- case FXDIB_Rgb32:
- return FXARGB_GETDIB(pos) | 0xff000000;
- case FXDIB_Argb:
- return FXARGB_GETDIB(pos);
- default:
- break;
- }
- return 0;
-}
-#endif
-void CFX_DIBitmap::SetPixel(int x, int y, FX_DWORD color)
-{
- if (m_pBuffer == NULL) {
- return;
- }
- if (x < 0 || x >= m_Width || y < 0 || y >= m_Height) {
- return;
- }
- FX_LPBYTE pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8;
- switch (GetFormat()) {
- case FXDIB_1bppMask:
- if (color >> 24) {
- *pos |= 1 << (7 - x % 8);
- } else {
- *pos &= ~(1 << (7 - x % 8));
- }
- break;
- case FXDIB_1bppRgb:
- if (m_pPalette) {
- if (color == m_pPalette[1]) {
- *pos |= 1 << (7 - x % 8);
- } else {
- *pos &= ~(1 << (7 - x % 8));
- }
- } else {
- if (color == 0xffffffff) {
- *pos |= 1 << (7 - x % 8);
- } else {
- *pos &= ~(1 << (7 - x % 8));
- }
- }
- break;
- case FXDIB_8bppMask:
- *pos = (FX_BYTE)(color >> 24);
- break;
- case FXDIB_8bppRgb: {
- if (m_pPalette) {
- for (int i = 0; i < 256; i ++) {
- if (m_pPalette[i] == color) {
- *pos = (FX_BYTE)i;
- return;
- }
- }
- *pos = 0;
- } else {
- *pos = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color));
- }
- break;
- }
- case FXDIB_Rgb:
- case FXDIB_Rgb32: {
- int alpha = FXARGB_A(color);
- pos[0] = (FXARGB_B(color) * alpha + pos[0] * (255 - alpha)) / 255;
- pos[1] = (FXARGB_G(color) * alpha + pos[1] * (255 - alpha)) / 255;
- pos[2] = (FXARGB_R(color) * alpha + pos[2] * (255 - alpha)) / 255;
- break;
- }
- case FXDIB_Rgba: {
- pos[0] = FXARGB_B(color);
- pos[1] = FXARGB_G(color);
- pos[2] = FXARGB_R(color);
- break;
- }
- case FXDIB_Argb:
- FXARGB_SETDIB(pos, color);
- break;
- default:
- break;
- }
-}
-void CFX_DIBitmap::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_bpp,
- int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const
-{
- if (m_pBuffer == NULL) {
- return;
- }
- int src_Bpp = m_bpp / 8;
- FX_LPBYTE scanline = m_pBuffer + line * m_Pitch;
- if (src_Bpp == 0) {
- for (int i = 0; i < clip_width; i ++) {
- FX_DWORD dest_x = clip_left + i;
- FX_DWORD src_x = dest_x * m_Width / dest_width;
- if (bFlipX) {
- src_x = m_Width - src_x - 1;
- }
-#ifdef FOXIT_CHROME_BUILD
- src_x %= m_Width;
-#endif
- dest_scan[i] = (scanline[src_x / 8] & (1 << (7 - src_x % 8))) ? 255 : 0;
- }
- } else if (src_Bpp == 1) {
- for (int i = 0; i < clip_width; i ++) {
- FX_DWORD dest_x = clip_left + i;
- FX_DWORD src_x = dest_x * m_Width / dest_width;
- if (bFlipX) {
- src_x = m_Width - src_x - 1;
- }
-#ifdef FOXIT_CHROME_BUILD
- src_x %= m_Width;
-#endif
- int dest_pos = i;
- if (m_pPalette) {
- if (!IsCmykImage()) {
- dest_pos *= 3;
- FX_ARGB argb = m_pPalette[scanline[src_x]];
- dest_scan[dest_pos] = FXARGB_B(argb);
- dest_scan[dest_pos + 1] = FXARGB_G(argb);
- dest_scan[dest_pos + 2] = FXARGB_R(argb);
- } else {
- dest_pos *= 4;
- FX_CMYK cmyk = m_pPalette[scanline[src_x]];
- dest_scan[dest_pos] = FXSYS_GetCValue(cmyk);
- dest_scan[dest_pos + 1] = FXSYS_GetMValue(cmyk);
- dest_scan[dest_pos + 2] = FXSYS_GetYValue(cmyk);
- dest_scan[dest_pos + 3] = FXSYS_GetKValue(cmyk);
- }
- } else {
- dest_scan[dest_pos] = scanline[src_x];
- }
- }
- } else {
- for (int i = 0; i < clip_width; i ++) {
- FX_DWORD dest_x = clip_left + i;
- FX_DWORD src_x = bFlipX ? (m_Width - dest_x * m_Width / dest_width - 1) * src_Bpp : (dest_x * m_Width / dest_width) * src_Bpp;
-#ifdef FOXIT_CHROME_BUILD
- src_x %= m_Width * src_Bpp;
-#endif
- int dest_pos = i * src_Bpp;
- for (int b = 0; b < src_Bpp; b ++) {
- dest_scan[dest_pos + b] = scanline[src_x + b];
- }
- }
- }
-}
-FX_BOOL CFX_DIBitmap::ConvertColorScale(FX_DWORD forecolor, FX_DWORD backcolor)
-{
- ASSERT(!IsAlphaMask());
- if (m_pBuffer == NULL || IsAlphaMask()) {
- return FALSE;
- }
- int fc, fm, fy, fk, bc, bm, by, bk;
- int fr, fg, fb, br, bg, bb;
- FX_BOOL isCmykImage = IsCmykImage();
- if (isCmykImage) {
- fc = FXSYS_GetCValue(forecolor);
- fm = FXSYS_GetMValue(forecolor);
- fy = FXSYS_GetYValue(forecolor);
- fk = FXSYS_GetKValue(forecolor);
- bc = FXSYS_GetCValue(backcolor);
- bm = FXSYS_GetMValue(backcolor);
- by = FXSYS_GetYValue(backcolor);
- bk = FXSYS_GetKValue(backcolor);
- } else {
- fr = FXSYS_GetRValue(forecolor);
- fg = FXSYS_GetGValue(forecolor);
- fb = FXSYS_GetBValue(forecolor);
- br = FXSYS_GetRValue(backcolor);
- bg = FXSYS_GetGValue(backcolor);
- bb = FXSYS_GetBValue(backcolor);
- }
- if (m_bpp <= 8) {
- if (isCmykImage) {
- if (forecolor == 0xff && backcolor == 0 && m_pPalette == NULL) {
- return TRUE;
- }
- } else if (forecolor == 0 && backcolor == 0xffffff && m_pPalette == NULL) {
- return TRUE;
- }
- if (m_pPalette == NULL) {
- BuildPalette();
- }
- int size = 1 << m_bpp;
- if (isCmykImage) {
- for (int i = 0; i < size; i ++) {
- FX_BYTE b, g, r;
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(m_pPalette[i]), FXSYS_GetMValue(m_pPalette[i]), FXSYS_GetYValue(m_pPalette[i]), FXSYS_GetKValue(m_pPalette[i]),
- r, g, b);
- int gray = 255 - FXRGB2GRAY(r, g, b);
- m_pPalette[i] = CmykEncode(bc + (fc - bc) * gray / 255, bm + (fm - bm) * gray / 255,
- by + (fy - by) * gray / 255, bk + (fk - bk) * gray / 255);
- }
- } else
- for (int i = 0; i < size; i ++) {
- int gray = FXRGB2GRAY(FXARGB_R(m_pPalette[i]), FXARGB_G(m_pPalette[i]), FXARGB_B(m_pPalette[i]));
- m_pPalette[i] = FXARGB_MAKE(0xff, br + (fr - br) * gray / 255, bg + (fg - bg) * gray / 255,
- bb + (fb - bb) * gray / 255);
- }
- return TRUE;
- }
- if (isCmykImage) {
- if (forecolor == 0xff && backcolor == 0x00) {
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE scanline = m_pBuffer + row * m_Pitch;
- for (int col = 0; col < m_Width; col ++) {
- FX_BYTE b, g, r;
- AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3],
- r, g, b);
- *scanline ++ = 0;
- *scanline ++ = 0;
- *scanline ++ = 0;
- *scanline ++ = 255 - FXRGB2GRAY(r, g, b);
- }
- }
- return TRUE;
- }
- } else if (forecolor == 0 && backcolor == 0xffffff) {
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE scanline = m_pBuffer + row * m_Pitch;
- int gap = m_bpp / 8 - 2;
- for (int col = 0; col < m_Width; col ++) {
- int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]);
- *scanline ++ = gray;
- *scanline ++ = gray;
- *scanline = gray;
- scanline += gap;
- }
- }
- return TRUE;
- }
- if (isCmykImage) {
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE scanline = m_pBuffer + row * m_Pitch;
- for (int col = 0; col < m_Width; col ++) {
- FX_BYTE b, g, r;
- AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3],
- r, g, b);
- int gray = 255 - FXRGB2GRAY(r, g, b);
- *scanline ++ = bc + (fc - bc) * gray / 255;
- *scanline ++ = bm + (fm - bm) * gray / 255;
- *scanline ++ = by + (fy - by) * gray / 255;
- *scanline ++ = bk + (fk - bk) * gray / 255;
- }
- }
- } else
- for (int row = 0; row < m_Height; row ++) {
- FX_LPBYTE scanline = m_pBuffer + row * m_Pitch;
- int gap = m_bpp / 8 - 2;
- for (int col = 0; col < m_Width; col ++) {
- int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]);
- *scanline ++ = bb + (fb - bb) * gray / 255;
- *scanline ++ = bg + (fg - bg) * gray / 255;
- *scanline = br + (fr - br) * gray / 255;
- scanline += gap;
- }
- }
- return TRUE;
-}
-FX_BOOL CFX_DIBitmap::DitherFS(const FX_DWORD* pPalette, int pal_size, const FX_RECT* pRect)
-{
- if (m_pBuffer == NULL) {
- return FALSE;
- }
- if (m_bpp != 8 && m_pPalette != NULL && m_AlphaFlag != 0) {
- return FALSE;
- }
- if (m_Width < 4 && m_Height < 4) {
- return FALSE;
- }
- FX_RECT rect(0, 0, m_Width, m_Height);
- if (pRect) {
- rect.Intersect(*pRect);
- }
- FX_BYTE translate[256];
- for (int i = 0; i < 256; i ++) {
- int err2 = 65536;
- for (int j = 0; j < pal_size; j ++) {
- FX_BYTE entry = (FX_BYTE)pPalette[j];
- int err = (int)entry - i;
- if (err * err < err2) {
- err2 = err * err;
- translate[i] = entry;
- }
- }
- }
- for (int row = rect.top; row < rect.bottom; row ++) {
- FX_LPBYTE scan = m_pBuffer + row * m_Pitch;
- FX_LPBYTE next_scan = m_pBuffer + (row + 1) * m_Pitch;
- for (int col = rect.left; col < rect.right; col ++) {
- int src_pixel = scan[col];
- int dest_pixel = translate[src_pixel];
- scan[col] = (FX_BYTE)dest_pixel;
- int error = -dest_pixel + src_pixel;
- if (col < rect.right - 1) {
- int src = scan[col + 1];
- src += error * 7 / 16;
- if (src > 255) {
- scan[col + 1] = 255;
- } else if (src < 0) {
- scan[col + 1] = 0;
- } else {
- scan[col + 1] = src;
- }
- }
- if (col < rect.right - 1 && row < rect.bottom - 1) {
- int src = next_scan[col + 1];
- src += error * 1 / 16;
- if (src > 255) {
- next_scan[col + 1] = 255;
- } else if (src < 0) {
- next_scan[col + 1] = 0;
- } else {
- next_scan[col + 1] = src;
- }
- }
- if (row < rect.bottom - 1) {
- int src = next_scan[col];
- src += error * 5 / 16;
- if (src > 255) {
- next_scan[col] = 255;
- } else if (src < 0) {
- next_scan[col] = 0;
- } else {
- next_scan[col] = src;
- }
- }
- if (col > rect.left && row < rect.bottom - 1) {
- int src = next_scan[col - 1];
- src += error * 3 / 16;
- if (src > 255) {
- next_scan[col - 1] = 255;
- } else if (src < 0) {
- next_scan[col - 1] = 0;
- } else {
- next_scan[col - 1] = src;
- }
- }
- }
- }
- return TRUE;
-}
-CFX_DIBitmap* CFX_DIBSource::FlipImage(FX_BOOL bXFlip, FX_BOOL bYFlip) const
-{
- CFX_DIBitmap* pFlipped = FX_NEW CFX_DIBitmap;
- if (!pFlipped) {
- return NULL;
- }
- if (!pFlipped->Create(m_Width, m_Height, GetFormat())) {
- delete pFlipped;
- return NULL;
- }
- pFlipped->CopyPalette(m_pPalette);
- FX_LPBYTE pDestBuffer = pFlipped->GetBuffer();
- int Bpp = m_bpp / 8;
- for (int row = 0; row < m_Height; row ++) {
- FX_LPCBYTE src_scan = GetScanline(row);
- FX_LPBYTE dest_scan = pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row);
- if (!bXFlip) {
- FXSYS_memcpy32(dest_scan, src_scan, m_Pitch);
- continue;
- }
- if (m_bpp == 1) {
- FXSYS_memset32(dest_scan, 0, m_Pitch);
- for (int col = 0; col < m_Width; col ++)
- if (src_scan[col / 8] & (1 << (7 - col % 8))) {
- int dest_col = m_Width - col - 1;
- dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8));
- }
- } else {
- dest_scan += (m_Width - 1) * Bpp;
- if (Bpp == 1) {
- for (int col = 0; col < m_Width; col ++) {
- *dest_scan = *src_scan;
- dest_scan --;
- src_scan ++;
- }
- } else if (Bpp == 3) {
- for (int col = 0; col < m_Width; col ++) {
- dest_scan[0] = src_scan[0];
- dest_scan[1] = src_scan[1];
- dest_scan[2] = src_scan[2];
- dest_scan -= 3;
- src_scan += 3;
- }
- } else {
- ASSERT(Bpp == 4);
- for (int col = 0; col < m_Width; col ++) {
- *(FX_DWORD*)dest_scan = *(FX_DWORD*)src_scan;
- dest_scan -= 4;
- src_scan += 4;
- }
- }
- }
- }
- if (m_pAlphaMask) {
- pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer();
- FX_DWORD dest_pitch = pFlipped->m_pAlphaMask->GetPitch();
- for (int row = 0; row < m_Height; row ++) {
- FX_LPCBYTE src_scan = m_pAlphaMask->GetScanline(row);
- FX_LPBYTE dest_scan = pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row);
- if (!bXFlip) {
- FXSYS_memcpy32(dest_scan, src_scan, dest_pitch);
- continue;
- }
- dest_scan += (m_Width - 1);
- for (int col = 0; col < m_Width; col ++) {
- *dest_scan = *src_scan;
- dest_scan --;
- src_scan ++;
- }
- }
- }
- return pFlipped;
-}
-CFX_DIBExtractor::CFX_DIBExtractor(const CFX_DIBSource* pSrc)
-{
- m_pBitmap = NULL;
- if (pSrc->GetBuffer() == NULL) {
- m_pBitmap = pSrc->Clone();
- } else {
- m_pBitmap = FX_NEW CFX_DIBitmap;
- if (!m_pBitmap) {
- return;
- }
- if (!m_pBitmap->Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat(), pSrc->GetBuffer())) {
- delete m_pBitmap;
- m_pBitmap = NULL;
- return;
- }
- m_pBitmap->CopyPalette(pSrc->GetPalette());
- m_pBitmap->CopyAlphaMask(pSrc->m_pAlphaMask);
- }
-}
-CFX_DIBExtractor::~CFX_DIBExtractor()
-{
- if (m_pBitmap) {
- delete m_pBitmap;
- }
-}
-CFX_FilteredDIB::CFX_FilteredDIB()
-{
- m_pScanline = NULL;
- m_pSrc = NULL;
-}
-CFX_FilteredDIB::~CFX_FilteredDIB()
-{
- if (m_pSrc && m_bAutoDropSrc) {
- delete m_pSrc;
- }
- if (m_pScanline) {
- FX_Free(m_pScanline);
- }
-}
-void CFX_FilteredDIB::LoadSrc(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc)
-{
- m_pSrc = pSrc;
- m_bAutoDropSrc = bAutoDropSrc;
- m_Width = pSrc->GetWidth();
- m_Height = pSrc->GetHeight();
- FXDIB_Format format = GetDestFormat();
- m_bpp = (FX_BYTE)format;
- m_AlphaFlag = (FX_BYTE)(format >> 8);
- m_Pitch = (m_Width * (format & 0xff) + 31) / 32 * 4;
- m_pPalette = GetDestPalette();
- m_pScanline = FX_Alloc(FX_BYTE, m_Pitch);
-}
-FX_LPCBYTE CFX_FilteredDIB::GetScanline(int line) const
-{
- TranslateScanline(m_pScanline, m_pSrc->GetScanline(line));
- return m_pScanline;
-}
-void CFX_FilteredDIB::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_bpp,
- int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const
-{
- m_pSrc->DownSampleScanline(line, dest_scan, dest_bpp, dest_width, bFlipX, clip_left, clip_width);
- TranslateDownSamples(dest_scan, dest_scan, clip_width, dest_bpp);
-}
-CFX_ImageRenderer::CFX_ImageRenderer()
-{
- m_Status = 0;
- m_pTransformer = NULL;
- m_bRgbByteOrder = FALSE;
- m_BlendType = FXDIB_BLEND_NORMAL;
-}
-CFX_ImageRenderer::~CFX_ImageRenderer()
-{
- if (m_pTransformer) {
- delete m_pTransformer;
- }
-}
-extern FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, int width, int height, FX_BOOL bFlipX, FX_BOOL bFlipY);
-FX_BOOL CFX_ImageRenderer::Start(CFX_DIBitmap* pDevice, const CFX_ClipRgn* pClipRgn,
- const CFX_DIBSource* pSource, int bitmap_alpha,
- FX_DWORD mask_color, const CFX_AffineMatrix* pMatrix,
- FX_DWORD dib_flags, FX_BOOL bRgbByteOrder,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- m_Matrix = *pMatrix;
- CFX_FloatRect image_rect_f = m_Matrix.GetUnitRect();
- FX_RECT image_rect = image_rect_f.GetOutterRect();
- m_ClipBox = pClipRgn ? pClipRgn->GetBox() : FX_RECT(0, 0, pDevice->GetWidth(), pDevice->GetHeight());
- m_ClipBox.Intersect(image_rect);
- if (m_ClipBox.IsEmpty()) {
- return FALSE;
- }
- m_pDevice = pDevice;
- m_pClipRgn = pClipRgn;
- m_MaskColor = mask_color;
- m_BitmapAlpha = bitmap_alpha;
- m_Matrix = *pMatrix;
- m_Flags = dib_flags;
- m_AlphaFlag = alpha_flag;
- m_pIccTransform = pIccTransform;
- m_bRgbByteOrder = bRgbByteOrder;
- m_BlendType = blend_type;
- FX_BOOL ret = TRUE;
- if ((FXSYS_fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) ||
- (FXSYS_fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0) ) {
- if (FXSYS_fabs(m_Matrix.a) < FXSYS_fabs(m_Matrix.b) / 20 && FXSYS_fabs(m_Matrix.d) < FXSYS_fabs(m_Matrix.c) / 20 &&
- FXSYS_fabs(m_Matrix.a) < 0.5f && FXSYS_fabs(m_Matrix.d) < 0.5f) {
- int dest_width = image_rect.Width();
- int dest_height = image_rect.Height();
- FX_RECT bitmap_clip = m_ClipBox;
- bitmap_clip.Offset(-image_rect.left, -image_rect.top);
- bitmap_clip = _FXDIB_SwapClipBox(bitmap_clip, dest_width, dest_height, m_Matrix.c > 0, m_Matrix.b < 0);
- m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox, TRUE,
- m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder, alpha_flag, pIccTransform, m_BlendType);
- if (!m_Stretcher.Start(&m_Composer, pSource, dest_height, dest_width, bitmap_clip, dib_flags)) {
- return FALSE;
- }
- m_Status = 1;
- return TRUE;
- }
- m_Status = 2;
- m_pTransformer = FX_NEW CFX_ImageTransformer;
- if (!m_pTransformer) {
- return FALSE;
- }
- m_pTransformer->Start(pSource, &m_Matrix, dib_flags, &m_ClipBox);
- return TRUE;
- }
- int dest_width = image_rect.Width();
- if (m_Matrix.a < 0) {
- dest_width = -dest_width;
- }
- int dest_height = image_rect.Height();
- if (m_Matrix.d > 0) {
- dest_height = -dest_height;
- }
- if (dest_width == 0 || dest_height == 0) {
- return FALSE;
- }
- FX_RECT bitmap_clip = m_ClipBox;
- bitmap_clip.Offset(-image_rect.left, -image_rect.top);
- m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color,
- m_ClipBox, FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_flag, pIccTransform, m_BlendType);
- m_Status = 1;
- ret = m_Stretcher.Start(&m_Composer, pSource, dest_width, dest_height, bitmap_clip, dib_flags);
- return ret;
-}
-FX_BOOL CFX_ImageRenderer::Continue(IFX_Pause* pPause)
-{
- if (m_Status == 1) {
- return m_Stretcher.Continue(pPause);
- } else if (m_Status == 2) {
- if (m_pTransformer->Continue(pPause)) {
- return TRUE;
- }
- CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
- if (pBitmap == NULL) {
- return FALSE;
- }
- if (pBitmap->GetBuffer() == NULL) {
- delete pBitmap;
- return FALSE;
- }
- if (pBitmap->IsAlphaMask()) {
- if (m_BitmapAlpha != 255) {
- if (m_AlphaFlag >> 8) {
- m_AlphaFlag = (((FX_BYTE)((m_AlphaFlag & 0xff) * m_BitmapAlpha / 255)) | ((m_AlphaFlag >> 8) << 8));
- } else {
- m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, m_BitmapAlpha);
- }
- }
- m_pDevice->CompositeMask(m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop,
- pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, m_MaskColor,
- 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform);
- } else {
- if (m_BitmapAlpha != 255) {
- pBitmap->MultiplyAlpha(m_BitmapAlpha);
- }
- m_pDevice->CompositeBitmap(m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop,
- pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOrder, m_pIccTransform);
- }
- delete pBitmap;
- return FALSE;
- }
- return FALSE;
-}
-CFX_BitmapStorer::CFX_BitmapStorer()
-{
- m_pBitmap = NULL;
-}
-CFX_BitmapStorer::~CFX_BitmapStorer()
-{
- if (m_pBitmap) {
- delete m_pBitmap;
- }
-}
-CFX_DIBitmap* CFX_BitmapStorer::Detach()
-{
- CFX_DIBitmap* pBitmap = m_pBitmap;
- m_pBitmap = NULL;
- return pBitmap;
-}
-void CFX_BitmapStorer::Replace(CFX_DIBitmap* pBitmap)
-{
- if (m_pBitmap) {
- delete m_pBitmap;
- }
- m_pBitmap = pBitmap;
-}
-void CFX_BitmapStorer::ComposeScanline(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
-{
- FX_LPBYTE dest_buf = (FX_LPBYTE)m_pBitmap->GetScanline(line);
- FX_LPBYTE dest_alpha_buf = m_pBitmap->m_pAlphaMask ?
- (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(line) : NULL;
- if (dest_buf) {
- FXSYS_memcpy32(dest_buf, scanline, m_pBitmap->GetPitch());
- }
- if (dest_alpha_buf) {
- FXSYS_memcpy32(dest_alpha_buf, scan_extra_alpha, m_pBitmap->m_pAlphaMask->GetPitch());
- }
-}
-FX_BOOL CFX_BitmapStorer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette)
-{
- m_pBitmap = FX_NEW CFX_DIBitmap;
- if (!m_pBitmap) {
- return FALSE;
- }
- if (!m_pBitmap->Create(width, height, src_format)) {
- delete m_pBitmap;
- m_pBitmap = NULL;
- return FALSE;
- }
- if (pSrcPalette) {
- m_pBitmap->CopyPalette(pSrcPalette);
- }
- return TRUE;
-}
+// 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 "../../../include/fxge/fx_dib.h"
+#include "../../../include/fxge/fx_ge.h"
+#include "../../../include/fxcodec/fx_codec.h"
+#include "dib_int.h"
+#include <limits.h>
+FX_BOOL ConvertBuffer(FXDIB_Format dest_format, FX_LPBYTE dest_buf, int dest_pitch, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, FX_DWORD*& pal, void* pIccTransform);
+void CmykDecode(FX_DWORD cmyk, int& c, int& m, int& y, int& k)
+{
+ c = FXSYS_GetCValue(cmyk);
+ m = FXSYS_GetMValue(cmyk);
+ y = FXSYS_GetYValue(cmyk);
+ k = FXSYS_GetKValue(cmyk);
+}
+void ArgbDecode(FX_DWORD argb, int& a, int& r, int& g, int& b)
+{
+ a = FXARGB_A(argb);
+ r = FXARGB_R(argb);
+ g = FXARGB_G(argb);
+ b = FXARGB_B(argb);
+}
+void ArgbDecode(FX_DWORD argb, int& a, FX_COLORREF& rgb)
+{
+ a = FXARGB_A(argb);
+ rgb = FXSYS_RGB(FXARGB_R(argb), FXARGB_G(argb), FXARGB_B(argb));
+}
+FX_DWORD ArgbEncode(int a, FX_COLORREF rgb)
+{
+ return FXARGB_MAKE(a, FXSYS_GetRValue(rgb), FXSYS_GetGValue(rgb), FXSYS_GetBValue(rgb));
+}
+CFX_DIBSource::CFX_DIBSource()
+{
+ m_bpp = 0;
+ m_AlphaFlag = 0;
+ m_Width = m_Height = 0;
+ m_Pitch = 0;
+ m_pPalette = NULL;
+ m_pAlphaMask = NULL;
+}
+CFX_DIBSource::~CFX_DIBSource()
+{
+ if (m_pPalette) {
+ FX_Free(m_pPalette);
+ }
+ if (m_pAlphaMask) {
+ delete m_pAlphaMask;
+ }
+}
+CFX_DIBitmap::CFX_DIBitmap()
+{
+ m_bExtBuf = FALSE;
+ m_pBuffer = NULL;
+ m_pPalette = NULL;
+}
+#define _MAX_OOM_LIMIT_ 12000000
+FX_BOOL CFX_DIBitmap::Create(int width, int height, FXDIB_Format format, FX_LPBYTE pBuffer, int pitch)
+{
+ m_pBuffer = NULL;
+ m_bpp = (FX_BYTE)format;
+ m_AlphaFlag = (FX_BYTE)(format >> 8);
+ m_Width = m_Height = m_Pitch = 0;
+ if (width <= 0 || height <= 0 || pitch < 0) {
+ return FALSE;
+ }
+ if ((INT_MAX - 31) / width < (format & 0xff)) {
+ return FALSE;
+ }
+ if (!pitch) {
+ pitch = (width * (format & 0xff) + 31) / 32 * 4;
+ }
+ if ((1 << 30) / pitch < height) {
+ return FALSE;
+ }
+ if (pBuffer) {
+ m_pBuffer = pBuffer;
+ m_bExtBuf = TRUE;
+ } else {
+ int size = pitch * height + 4;
+ int oomlimit = _MAX_OOM_LIMIT_;
+ if (oomlimit >= 0 && size >= oomlimit) {
+ m_pBuffer = FX_AllocNL(FX_BYTE, size);
+ } else {
+ m_pBuffer = FX_Alloc(FX_BYTE, size);
+ }
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ FXSYS_memset32(m_pBuffer, 0, sizeof (FX_BYTE) * size);
+ }
+ m_Width = width;
+ m_Height = height;
+ m_Pitch = pitch;
+ if (HasAlpha() && format != FXDIB_Argb) {
+ FX_BOOL ret = TRUE;
+ ret = BuildAlphaMask();
+ if (!ret) {
+ if (!m_bExtBuf && m_pBuffer) {
+ FX_Free(m_pBuffer);
+ m_pBuffer = NULL;
+ m_Width = m_Height = m_Pitch = 0;
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DIBitmap::Copy(const CFX_DIBSource* pSrc)
+{
+ if (m_pBuffer) {
+ return FALSE;
+ }
+ if (!Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat())) {
+ return FALSE;
+ }
+ CopyPalette(pSrc->GetPalette());
+ CopyAlphaMask(pSrc->m_pAlphaMask);
+ for (int row = 0; row < pSrc->GetHeight(); row ++) {
+ FXSYS_memcpy32(m_pBuffer + row * m_Pitch, pSrc->GetScanline(row), m_Pitch);
+ }
+ return TRUE;
+}
+CFX_DIBitmap::~CFX_DIBitmap()
+{
+ if (m_pBuffer && !m_bExtBuf) {
+ FX_Free(m_pBuffer);
+ }
+ m_pBuffer = NULL;
+}
+void CFX_DIBitmap::TakeOver(CFX_DIBitmap* pSrcBitmap)
+{
+ if (m_pBuffer && !m_bExtBuf) {
+ FX_Free(m_pBuffer);
+ }
+ if (m_pPalette) {
+ FX_Free(m_pPalette);
+ }
+ if (m_pAlphaMask) {
+ delete m_pAlphaMask;
+ }
+ m_pBuffer = pSrcBitmap->m_pBuffer;
+ m_pPalette = pSrcBitmap->m_pPalette;
+ m_pAlphaMask = pSrcBitmap->m_pAlphaMask;
+ pSrcBitmap->m_pBuffer = NULL;
+ pSrcBitmap->m_pPalette = NULL;
+ pSrcBitmap->m_pAlphaMask = NULL;
+ m_bpp = pSrcBitmap->m_bpp;
+ m_bExtBuf = pSrcBitmap->m_bExtBuf;
+ m_AlphaFlag = pSrcBitmap->m_AlphaFlag;
+ m_Width = pSrcBitmap->m_Width;
+ m_Height = pSrcBitmap->m_Height;
+ m_Pitch = pSrcBitmap->m_Pitch;
+}
+CFX_DIBitmap* CFX_DIBSource::Clone(const FX_RECT* pClip) const
+{
+ FX_RECT rect(0, 0, m_Width, m_Height);
+ if (pClip) {
+ rect.Intersect(*pClip);
+ if (rect.IsEmpty()) {
+ return NULL;
+ }
+ }
+ CFX_DIBitmap* pNewBitmap = FX_NEW CFX_DIBitmap;
+ if (!pNewBitmap) {
+ return NULL;
+ }
+ if (!pNewBitmap->Create(rect.Width(), rect.Height(), GetFormat())) {
+ delete pNewBitmap;
+ return NULL;
+ }
+ pNewBitmap->CopyPalette(m_pPalette);
+ pNewBitmap->CopyAlphaMask(m_pAlphaMask, pClip);
+ if (GetBPP() == 1 && rect.left % 8 != 0) {
+ int left_shift = rect.left % 32;
+ int right_shift = 32 - left_shift;
+ int dword_count = pNewBitmap->m_Pitch / 4;
+ for (int row = rect.top; row < rect.bottom; row ++) {
+ FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + rect.left / 32;
+ FX_DWORD* dest_scan = (FX_DWORD*)pNewBitmap->GetScanline(row - rect.top);
+ for (int i = 0; i < dword_count; i ++) {
+ dest_scan[i] = (src_scan[i] << left_shift) | (src_scan[i + 1] >> right_shift);
+ }
+ }
+ } else {
+ int copy_len = (pNewBitmap->GetWidth() * pNewBitmap->GetBPP() + 7) / 8;
+ if (m_Pitch < (FX_DWORD)copy_len) {
+ copy_len = m_Pitch;
+ }
+ for (int row = rect.top; row < rect.bottom; row ++) {
+ FX_LPCBYTE src_scan = GetScanline(row) + rect.left * m_bpp / 8;
+ FX_LPBYTE dest_scan = (FX_LPBYTE)pNewBitmap->GetScanline(row - rect.top);
+ FXSYS_memcpy32(dest_scan, src_scan, copy_len);
+ }
+ }
+ return pNewBitmap;
+}
+void CFX_DIBSource::BuildPalette()
+{
+ if (m_pPalette) {
+ return;
+ }
+ if (GetBPP() == 1) {
+ m_pPalette = FX_Alloc(FX_DWORD, 2);
+ if (!m_pPalette) {
+ return;
+ }
+ if(IsCmykImage()) {
+ m_pPalette[0] = 0xff;
+ m_pPalette[1] = 0;
+ } else {
+ m_pPalette[0] = 0xff000000;
+ m_pPalette[1] = 0xffffffff;
+ }
+ } else if (GetBPP() == 8) {
+ m_pPalette = FX_Alloc(FX_DWORD, 256);
+ if (!m_pPalette) {
+ return;
+ }
+ if(IsCmykImage()) {
+ for (int i = 0; i < 256; i ++) {
+ m_pPalette[i] = 0xff - i;
+ }
+ } else {
+ for (int i = 0; i < 256; i ++) {
+ m_pPalette[i] = 0xff000000 | (i * 0x10101);
+ }
+ }
+ }
+}
+FX_BOOL CFX_DIBSource::BuildAlphaMask()
+{
+ if (m_pAlphaMask) {
+ return TRUE;
+ }
+ m_pAlphaMask = FX_NEW CFX_DIBitmap;
+ if (!m_pAlphaMask) {
+ return FALSE;
+ }
+ if (!m_pAlphaMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
+ delete m_pAlphaMask;
+ m_pAlphaMask = NULL;
+ return FALSE;
+ }
+ FXSYS_memset8(m_pAlphaMask->GetBuffer(), 0xff, m_pAlphaMask->GetHeight()*m_pAlphaMask->GetPitch());
+ return TRUE;
+}
+FX_DWORD CFX_DIBSource::GetPaletteEntry(int index) const
+{
+ ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
+ if (m_pPalette) {
+ return m_pPalette[index];
+ }
+ if (IsCmykImage()) {
+ if (GetBPP() == 1) {
+ return index ? 0 : 0xff;
+ }
+ return 0xff - index;
+ }
+ if (GetBPP() == 1) {
+ return index ? 0xffffffff : 0xff000000;
+ }
+ return index * 0x10101 | 0xff000000;
+}
+void CFX_DIBSource::SetPaletteEntry(int index, FX_DWORD color)
+{
+ ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
+ if (m_pPalette == NULL) {
+ BuildPalette();
+ }
+ m_pPalette[index] = color;
+}
+int CFX_DIBSource::FindPalette(FX_DWORD color) const
+{
+ ASSERT((GetBPP() == 1 || GetBPP() == 8) && !IsAlphaMask());
+ if (m_pPalette == NULL) {
+ if (IsCmykImage()) {
+ if (GetBPP() == 1) {
+ return ((FX_BYTE)color == 0xff) ? 0 : 1;
+ }
+ return 0xff - (FX_BYTE)color;
+ }
+ if (GetBPP() == 1) {
+ return ((FX_BYTE)color == 0xff) ? 1 : 0;
+ }
+ return (FX_BYTE)color;
+ }
+ int palsize = (1 << GetBPP());
+ for (int i = 0; i < palsize; i ++)
+ if (m_pPalette[i] == color) {
+ return i;
+ }
+ return -1;
+}
+void CFX_DIBitmap::Clear(FX_DWORD color)
+{
+ if (m_pBuffer == NULL) {
+ return;
+ }
+ switch (GetFormat()) {
+ case FXDIB_1bppMask:
+ FXSYS_memset8(m_pBuffer, (color & 0xff000000) ? 0xff : 0, m_Pitch * m_Height);
+ break;
+ case FXDIB_1bppRgb: {
+ int index = FindPalette(color);
+ FXSYS_memset8(m_pBuffer, index ? 0xff : 0, m_Pitch * m_Height);
+ break;
+ }
+ case FXDIB_8bppMask:
+ FXSYS_memset8(m_pBuffer, color >> 24, m_Pitch * m_Height);
+ break;
+ case FXDIB_8bppRgb: {
+ int index = FindPalette(color);
+ FXSYS_memset8(m_pBuffer, index, m_Pitch * m_Height);
+ break;
+ }
+ case FXDIB_Rgb:
+ case FXDIB_Rgba: {
+ int a, r, g, b;
+ ArgbDecode(color, a, r, g, b);
+ if (r == g && g == b) {
+ FXSYS_memset8(m_pBuffer, r, m_Pitch * m_Height);
+ } else {
+ int byte_pos = 0;
+ for (int col = 0; col < m_Width; col ++) {
+ m_pBuffer[byte_pos++] = b;
+ m_pBuffer[byte_pos++] = g;
+ m_pBuffer[byte_pos++] = r;
+ }
+ for (int row = 1; row < m_Height; row ++) {
+ FXSYS_memcpy32(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch);
+ }
+ }
+ break;
+ }
+ case FXDIB_Rgb32:
+ case FXDIB_Argb: {
+ color = IsCmykImage() ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
+ for (int i = 0; i < m_Width; i ++) {
+ ((FX_DWORD*)m_pBuffer)[i] = color;
+ }
+ for (int row = 1; row < m_Height; row ++) {
+ FXSYS_memcpy32(m_pBuffer + row * m_Pitch, m_pBuffer, m_Pitch);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+}
+void CFX_DIBSource::GetOverlapRect(int& dest_left, int& dest_top, int& width, int& height,
+ int src_width, int src_height, int& src_left, int& src_top,
+ const CFX_ClipRgn* pClipRgn)
+{
+ if (width == 0 || height == 0) {
+ return;
+ }
+ ASSERT(width > 0 && height > 0);
+ if (dest_left > m_Width || dest_top > m_Height) {
+ width = 0;
+ height = 0;
+ return;
+ }
+ int x_offset = dest_left - src_left;
+ int y_offset = dest_top - src_top;
+ FX_RECT src_rect(src_left, src_top, src_left + width, src_top + height);
+ FX_RECT src_bound(0, 0, src_width, src_height);
+ src_rect.Intersect(src_bound);
+ FX_RECT dest_rect(src_rect.left + x_offset, src_rect.top + y_offset,
+ src_rect.right + x_offset, src_rect.bottom + y_offset);
+ FX_RECT dest_bound(0, 0, m_Width, m_Height);
+ dest_rect.Intersect(dest_bound);
+ if (pClipRgn) {
+ dest_rect.Intersect(pClipRgn->GetBox());
+ }
+ dest_left = dest_rect.left;
+ dest_top = dest_rect.top;
+ src_left = dest_left - x_offset;
+ src_top = dest_top - y_offset;
+ width = dest_rect.right - dest_rect.left;
+ height = dest_rect.bottom - dest_rect.top;
+}
+FX_BOOL CFX_DIBitmap::TransferBitmap(int dest_left, int dest_top, int width, int height,
+ const CFX_DIBSource* pSrcBitmap, int src_left, int src_top, void* pIccTransform)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ GetOverlapRect(dest_left, dest_top, width, height, pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(), src_left, src_top, NULL);
+ if (width == 0 || height == 0) {
+ return TRUE;
+ }
+ FXDIB_Format dest_format = GetFormat();
+ FXDIB_Format src_format = pSrcBitmap->GetFormat();
+ if (dest_format == src_format && pIccTransform == NULL) {
+ if (GetBPP() == 1) {
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row);
+ for (int col = 0; col < width; col ++) {
+ if (src_scan[(src_left + col) / 8] & (1 << (7 - (src_left + col) % 8))) {
+ dest_scan[(dest_left + col) / 8] |= 1 << (7 - (dest_left + col) % 8);
+ } else {
+ dest_scan[(dest_left + col) / 8] &= ~(1 << (7 - (dest_left + col) % 8));
+ }
+ }
+ }
+ } else {
+ int Bpp = GetBPP() / 8;
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_scan = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * Bpp;
+ FX_LPCBYTE src_scan = pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
+ FXSYS_memcpy32(dest_scan, src_scan, width * Bpp);
+ }
+ }
+ } else {
+ if (m_pPalette) {
+ return FALSE;
+ }
+ if (m_bpp == 8) {
+ dest_format = FXDIB_8bppMask;
+ }
+ FX_LPBYTE dest_buf = m_pBuffer + dest_top * m_Pitch + dest_left * GetBPP() / 8;
+ FX_DWORD* d_plt = NULL;
+ if(!ConvertBuffer(dest_format, dest_buf, m_Pitch, width, height, pSrcBitmap, src_left, src_top, d_plt, pIccTransform)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+#ifndef _FPDFAPI_MINI_
+FX_BOOL CFX_DIBitmap::TransferMask(int dest_left, int dest_top, int width, int height,
+ const CFX_DIBSource* pMask, FX_DWORD color, int src_left, int src_top, int alpha_flag, void* pIccTransform)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ ASSERT(HasAlpha() && (m_bpp >= 24));
+ ASSERT(pMask->IsAlphaMask());
+ if (!HasAlpha() || !pMask->IsAlphaMask() || m_bpp < 24) {
+ return FALSE;
+ }
+ GetOverlapRect(dest_left, dest_top, width, height, pMask->GetWidth(), pMask->GetHeight(), src_left, src_top, NULL);
+ if (width == 0 || height == 0) {
+ return TRUE;
+ }
+ int src_pitch = pMask->GetPitch();
+ int src_bpp = pMask->GetBPP();
+ int alpha;
+ FX_DWORD dst_color;
+ if (alpha_flag >> 8) {
+ alpha = alpha_flag & 0xff;
+ dst_color = FXCMYK_TODIB(color);
+ } else {
+ alpha = FXARGB_A(color);
+ dst_color = FXARGB_TODIB(color);
+ }
+ FX_LPBYTE color_p = (FX_LPBYTE)&dst_color;
+ if (pIccTransform && CFX_GEModule::Get()->GetCodecModule() && CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ pIccModule->TranslateScanline(pIccTransform, color_p, color_p, 1);
+ } else {
+ if (alpha_flag >> 8 && !IsCmykImage())
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), FXSYS_GetYValue(color), FXSYS_GetKValue(color),
+ color_p[2], color_p[1], color_p[0]);
+ else if (!(alpha_flag >> 8) && IsCmykImage()) {
+ return FALSE;
+ }
+ }
+ if(!IsCmykImage()) {
+ color_p[3] = (FX_BYTE)alpha;
+ }
+ if (GetFormat() == FXDIB_Argb) {
+ for (int row = 0; row < height; row ++) {
+ FX_DWORD* dest_pos = (FX_DWORD*)(m_pBuffer + (dest_top + row) * m_Pitch + dest_left * 4);
+ FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row);
+ if (src_bpp == 1) {
+ for (int col = 0; col < width; col ++) {
+ int src_bitpos = src_left + col;
+ if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) {
+ *dest_pos = dst_color;
+ } else {
+ *dest_pos = 0;
+ }
+ dest_pos ++;
+ }
+ } else {
+ src_scan += src_left;
+ dst_color = FXARGB_TODIB(dst_color);
+ dst_color &= 0xffffff;
+ for (int col = 0; col < width; col ++) {
+ FXARGB_SETDIB(dest_pos++, dst_color | ((alpha * (*src_scan++) / 255) << 24));
+ }
+ }
+ }
+ } else {
+ int comps = m_bpp / 8;
+ for (int row = 0; row < height; row ++) {
+ FX_LPBYTE dest_color_pos = m_pBuffer + (dest_top + row) * m_Pitch + dest_left * comps;
+ FX_LPBYTE dest_alpha_pos = (FX_LPBYTE)m_pAlphaMask->GetScanline(dest_top + row) + dest_left;
+ FX_LPCBYTE src_scan = pMask->GetScanline(src_top + row);
+ if (src_bpp == 1) {
+ for (int col = 0; col < width; col ++) {
+ int src_bitpos = src_left + col;
+ if (src_scan[src_bitpos / 8] & (1 << (7 - src_bitpos % 8))) {
+ FXSYS_memcpy32(dest_color_pos, color_p, comps);
+ *dest_alpha_pos = 0xff;
+ } else {
+ FXSYS_memset32(dest_color_pos, 0, comps);
+ *dest_alpha_pos = 0;
+ }
+ dest_color_pos += comps;
+ dest_alpha_pos ++;
+ }
+ } else {
+ src_scan += src_left;
+ for (int col = 0; col < width; col ++) {
+ FXSYS_memcpy32(dest_color_pos, color_p, comps);
+ dest_color_pos += comps;
+ *dest_alpha_pos++ = (alpha * (*src_scan++) / 255);
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+#endif
+void CFX_DIBSource::CopyPalette(const FX_DWORD* pSrc, FX_DWORD size)
+{
+ if (pSrc == NULL || GetBPP() > 8) {
+ if (m_pPalette) {
+ FX_Free(m_pPalette);
+ }
+ m_pPalette = NULL;
+ } else {
+ FX_DWORD pal_size = 1 << GetBPP();
+ if (m_pPalette == NULL) {
+ m_pPalette = FX_Alloc(FX_DWORD, pal_size);
+ }
+ if (!m_pPalette) {
+ return;
+ }
+ if (pal_size > size) {
+ pal_size = size;
+ }
+ FXSYS_memcpy32(m_pPalette, pSrc, pal_size * sizeof(FX_DWORD));
+ }
+}
+void CFX_DIBSource::GetPalette(FX_DWORD* pal, int alpha) const
+{
+ ASSERT(GetBPP() <= 8 && !IsCmykImage());
+ if (GetBPP() == 1) {
+ pal[0] = ((m_pPalette ? m_pPalette[0] : 0xff000000) & 0xffffff) | (alpha << 24);
+ pal[1] = ((m_pPalette ? m_pPalette[1] : 0xffffffff) & 0xffffff) | (alpha << 24);
+ return;
+ }
+ if (m_pPalette) {
+ for (int i = 0; i < 256; i ++) {
+ pal[i] = (m_pPalette[i] & 0x00ffffff) | (alpha << 24);
+ }
+ } else {
+ for (int i = 0; i < 256; i ++) {
+ pal[i] = (i * 0x10101) | (alpha << 24);
+ }
+ }
+}
+CFX_DIBitmap* CFX_DIBSource::GetAlphaMask(const FX_RECT* pClip) const
+{
+ ASSERT(GetFormat() == FXDIB_Argb);
+ FX_RECT rect(0, 0, m_Width, m_Height);
+ if (pClip) {
+ rect.Intersect(*pClip);
+ if (rect.IsEmpty()) {
+ return NULL;
+ }
+ }
+ CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
+ if (!pMask) {
+ return NULL;
+ }
+ if (!pMask->Create(rect.Width(), rect.Height(), FXDIB_8bppMask)) {
+ delete pMask;
+ return NULL;
+ }
+ for (int row = rect.top; row < rect.bottom; row ++) {
+ FX_LPCBYTE src_scan = GetScanline(row) + rect.left * 4 + 3;
+ FX_LPBYTE dest_scan = (FX_LPBYTE)pMask->GetScanline(row - rect.top);
+ for (int col = rect.left; col < rect.right; col ++) {
+ *dest_scan ++ = *src_scan;
+ src_scan += 4;
+ }
+ }
+ return pMask;
+}
+FX_BOOL CFX_DIBSource::CopyAlphaMask(const CFX_DIBSource* pAlphaMask, const FX_RECT* pClip)
+{
+ if (!HasAlpha() || GetFormat() == FXDIB_Argb) {
+ return FALSE;
+ }
+ if (pAlphaMask) {
+ FX_RECT rect(0, 0, pAlphaMask->m_Width, pAlphaMask->m_Height);
+ if (pClip) {
+ rect.Intersect(*pClip);
+ if (rect.IsEmpty() || rect.Width() != m_Width || rect.Height() != m_Height) {
+ return FALSE;
+ }
+ } else {
+ if (pAlphaMask->m_Width != m_Width || pAlphaMask->m_Height != m_Height) {
+ return FALSE;
+ }
+ }
+ for (int row = 0; row < m_Height; row ++)
+ FXSYS_memcpy32((void*)m_pAlphaMask->GetScanline(row),
+ pAlphaMask->GetScanline(row + rect.top) + rect.left, m_pAlphaMask->m_Pitch);
+ } else {
+ m_pAlphaMask->Clear(0xff000000);
+ }
+ return TRUE;
+}
+const int g_ChannelOffset[] = {0, 2, 1, 0, 0, 1, 2, 3, 3};
+FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, const CFX_DIBSource* pSrcBitmap, FXDIB_Channel srcChannel)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ CFX_DIBSource* pSrcClone = (CFX_DIBSource*)pSrcBitmap;
+ CFX_DIBitmap* pDst = this;
+ int destOffset, srcOffset;
+ if (srcChannel == FXDIB_Alpha) {
+ if (!pSrcBitmap->HasAlpha() && !pSrcBitmap->IsAlphaMask()) {
+ return FALSE;
+ }
+ if (pSrcBitmap->GetBPP() == 1) {
+ pSrcClone = pSrcBitmap->CloneConvert(FXDIB_8bppMask);
+ if (pSrcClone == NULL) {
+ return FALSE;
+ }
+ }
+ if(pSrcBitmap->GetFormat() == FXDIB_Argb) {
+ srcOffset = 3;
+ } else {
+ srcOffset = 0;
+ }
+ } else {
+ if (pSrcBitmap->IsAlphaMask()) {
+ return FALSE;
+ }
+ if (pSrcBitmap->GetBPP() < 24) {
+ if (pSrcBitmap->IsCmykImage()) {
+ pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x20));
+ } else {
+ pSrcClone = pSrcBitmap->CloneConvert((FXDIB_Format)((pSrcBitmap->GetFormat() & 0xff00) | 0x18));
+ }
+ if (pSrcClone == NULL) {
+ return FALSE;
+ }
+ }
+ srcOffset = g_ChannelOffset[srcChannel];
+ }
+ if (destChannel == FXDIB_Alpha) {
+ if (IsAlphaMask()) {
+ if(!ConvertFormat(FXDIB_8bppMask)) {
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ return FALSE;
+ }
+ destOffset = 0;
+ } else {
+ destOffset = 0;
+ if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ return FALSE;
+ }
+ if (GetFormat() == FXDIB_Argb) {
+ destOffset = 3;
+ }
+ }
+ } else {
+ if (IsAlphaMask()) {
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ return FALSE;
+ }
+ if (GetBPP() < 24) {
+ if (HasAlpha()) {
+ if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ return FALSE;
+ }
+ } else
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) {
+#else
+ if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) {
+#endif
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ return FALSE;
+ }
+ }
+ destOffset = g_ChannelOffset[destChannel];
+ }
+ if (srcChannel == FXDIB_Alpha && pSrcClone->m_pAlphaMask) {
+ CFX_DIBitmap* pAlphaMask = pSrcClone->m_pAlphaMask;
+ if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Height) {
+ if (pAlphaMask) {
+ pAlphaMask = pAlphaMask->StretchTo(m_Width, m_Height);
+ if (pAlphaMask == NULL) {
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ return FALSE;
+ }
+ }
+ }
+ if (pSrcClone != pSrcBitmap) {
+ pSrcClone->m_pAlphaMask = NULL;
+ delete pSrcClone;
+ }
+ pSrcClone = pAlphaMask;
+ srcOffset = 0;
+ } else if (pSrcClone->GetWidth() != m_Width || pSrcClone->GetHeight() != m_Height) {
+ CFX_DIBitmap* pSrcMatched = pSrcClone->StretchTo(m_Width, m_Height);
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ if (pSrcMatched == NULL) {
+ return FALSE;
+ }
+ pSrcClone = pSrcMatched;
+ }
+ if (destChannel == FXDIB_Alpha && m_pAlphaMask) {
+ pDst = m_pAlphaMask;
+ destOffset = 0;
+ }
+ int srcBytes = pSrcClone->GetBPP() / 8;
+ int destBytes = pDst->GetBPP() / 8;
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE dest_pos = (FX_LPBYTE)pDst->GetScanline(row) + destOffset;
+ FX_LPCBYTE src_pos = pSrcClone->GetScanline(row) + srcOffset;
+ for (int col = 0; col < m_Width; col ++) {
+ *dest_pos = *src_pos;
+ dest_pos += destBytes;
+ src_pos += srcBytes;
+ }
+ }
+ if (pSrcClone != pSrcBitmap && pSrcClone != pSrcBitmap->m_pAlphaMask) {
+ delete pSrcClone;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DIBitmap::LoadChannel(FXDIB_Channel destChannel, int value)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ int destOffset;
+ if (destChannel == FXDIB_Alpha) {
+ if (IsAlphaMask()) {
+ if(!ConvertFormat(FXDIB_8bppMask)) {
+ return FALSE;
+ }
+ destOffset = 0;
+ } else {
+ destOffset = 0;
+ if(!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
+ return FALSE;
+ }
+ if (GetFormat() == FXDIB_Argb) {
+ destOffset = 3;
+ }
+ }
+ } else {
+ if (IsAlphaMask()) {
+ return FALSE;
+ }
+ if (GetBPP() < 24) {
+ if (HasAlpha()) {
+ if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyka : FXDIB_Argb)) {
+ return FALSE;
+ }
+ } else
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb)) {
+ return FALSE;
+ }
+#else
+ if (!ConvertFormat(IsCmykImage() ? FXDIB_Cmyk : FXDIB_Rgb32)) {
+ return FALSE;
+ }
+#endif
+ }
+ destOffset = g_ChannelOffset[destChannel];
+ }
+ int Bpp = GetBPP() / 8;
+ if (Bpp == 1) {
+ FXSYS_memset8(m_pBuffer, value, m_Height * m_Pitch);
+ return TRUE;
+ }
+ if (destChannel == FXDIB_Alpha && m_pAlphaMask) {
+ FXSYS_memset8(m_pAlphaMask->GetBuffer(), value, m_pAlphaMask->GetHeight()*m_pAlphaMask->GetPitch());
+ return TRUE;
+ }
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch + destOffset;
+ for (int col = 0; col < m_Width; col ++) {
+ *scan_line = value;
+ scan_line += Bpp;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DIBitmap::MultiplyAlpha(const CFX_DIBSource* pSrcBitmap)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ ASSERT(pSrcBitmap->IsAlphaMask());
+ if (!pSrcBitmap->IsAlphaMask()) {
+ return FALSE;
+ }
+ if (!IsAlphaMask() && !HasAlpha()) {
+ return LoadChannel(FXDIB_Alpha, pSrcBitmap, FXDIB_Alpha);
+ }
+ CFX_DIBitmap* pSrcClone = (CFX_DIBitmap*)pSrcBitmap;
+ if (pSrcBitmap->GetWidth() != m_Width || pSrcBitmap->GetHeight() != m_Height) {
+ pSrcClone = pSrcBitmap->StretchTo(m_Width, m_Height);
+ ASSERT(pSrcClone != NULL);
+ if (pSrcClone == NULL) {
+ return FALSE;
+ }
+ }
+ if (IsAlphaMask()) {
+ if(!ConvertFormat(FXDIB_8bppMask)) {
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ return FALSE;
+ }
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE dest_scan = m_pBuffer + m_Pitch * row;
+ FX_LPBYTE src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row;
+ if (pSrcClone->GetBPP() == 1) {
+ for (int col = 0; col < m_Width; col ++) {
+ if (!((1 << (7 - col % 8)) & src_scan[col / 8])) {
+ dest_scan[col] = 0;
+ }
+ }
+ } else {
+ for (int col = 0; col < m_Width; col ++) {
+ *dest_scan = (*dest_scan) * src_scan[col] / 255;
+ dest_scan ++;
+ }
+ }
+ }
+ } else {
+ if(GetFormat() == FXDIB_Argb) {
+ if (pSrcClone->GetBPP() == 1) {
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ return FALSE;
+ }
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE dest_scan = m_pBuffer + m_Pitch * row + 3;
+ FX_LPBYTE src_scan = pSrcClone->m_pBuffer + pSrcClone->m_Pitch * row;
+ for (int col = 0; col < m_Width; col ++) {
+ *dest_scan = (*dest_scan) * src_scan[col] / 255;
+ dest_scan += 4;
+ }
+ }
+ } else {
+ m_pAlphaMask->MultiplyAlpha(pSrcClone);
+ }
+ }
+ if (pSrcClone != pSrcBitmap) {
+ delete pSrcClone;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DIBitmap::GetGrayData(void* pIccTransform)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ switch (GetFormat()) {
+ case FXDIB_1bppRgb: {
+ if (m_pPalette == NULL) {
+ return FALSE;
+ }
+ FX_BYTE gray[2];
+ for (int i = 0; i < 2; i ++) {
+ int r = (FX_BYTE)(m_pPalette[i] >> 16);
+ int g = (FX_BYTE)(m_pPalette[i] >> 8);
+ int b = (FX_BYTE)m_pPalette[i];
+ gray[i] = (FX_BYTE)FXRGB2GRAY(r, g, b);
+ }
+ CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
+ if (!pMask) {
+ return FALSE;
+ }
+ if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
+ delete pMask;
+ return FALSE;
+ }
+ FXSYS_memset8(pMask->GetBuffer(), gray[0], pMask->GetPitch() * m_Height);
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch;
+ FX_LPBYTE dest_pos = (FX_LPBYTE)pMask->GetScanline(row);
+ for (int col = 0; col < m_Width; col ++) {
+ if (src_pos[col / 8] & (1 << (7 - col % 8))) {
+ *dest_pos = gray[1];
+ }
+ dest_pos ++;
+ }
+ }
+ TakeOver(pMask);
+ delete pMask;
+ break;
+ }
+ case FXDIB_8bppRgb: {
+ if (m_pPalette == NULL) {
+ return FALSE;
+ }
+ FX_BYTE gray[256];
+ for (int i = 0; i < 256; i ++) {
+ int r = (FX_BYTE)(m_pPalette[i] >> 16);
+ int g = (FX_BYTE)(m_pPalette[i] >> 8);
+ int b = (FX_BYTE)m_pPalette[i];
+ gray[i] = (FX_BYTE)FXRGB2GRAY(r, g, b);
+ }
+ CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
+ if (!pMask) {
+ return FALSE;
+ }
+ if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
+ delete pMask;
+ return FALSE;
+ }
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPitch();
+ FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch;
+ for (int col = 0; col < m_Width; col ++) {
+ *dest_pos ++ = gray[*src_pos ++];
+ }
+ }
+ TakeOver(pMask);
+ delete pMask;
+ break;
+ }
+ case FXDIB_Rgb: {
+ CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
+ if (!pMask) {
+ return FALSE;
+ }
+ if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
+ delete pMask;
+ return FALSE;
+ }
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch;
+ FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPitch();
+ for (int col = 0; col < m_Width; col ++) {
+ *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos);
+ src_pos += 3;
+ }
+ }
+ TakeOver(pMask);
+ delete pMask;
+ break;
+ }
+ case FXDIB_Rgb32: {
+ CFX_DIBitmap* pMask = FX_NEW CFX_DIBitmap;
+ if (!pMask) {
+ return FALSE;
+ }
+ if (!pMask->Create(m_Width, m_Height, FXDIB_8bppMask)) {
+ delete pMask;
+ return FALSE;
+ }
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE src_pos = m_pBuffer + row * m_Pitch;
+ FX_LPBYTE dest_pos = pMask->GetBuffer() + row * pMask->GetPitch();
+ for (int col = 0; col < m_Width; col ++) {
+ *dest_pos ++ = FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos);
+ src_pos += 4;
+ }
+ }
+ TakeOver(pMask);
+ delete pMask;
+ break;
+ }
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DIBitmap::MultiplyAlpha(int alpha)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ switch (GetFormat()) {
+ case FXDIB_1bppMask:
+ if (!ConvertFormat(FXDIB_8bppMask)) {
+ return FALSE;
+ }
+ MultiplyAlpha(alpha);
+ break;
+ case FXDIB_8bppMask: {
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch;
+ for (int col = 0; col < m_Width; col ++) {
+ scan_line[col] = scan_line[col] * alpha / 255;
+ }
+ }
+ break;
+ }
+ case FXDIB_Argb: {
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE scan_line = m_pBuffer + row * m_Pitch + 3;
+ for (int col = 0; col < m_Width; col ++) {
+ *scan_line = (*scan_line) * alpha / 255;
+ scan_line += 4;
+ }
+ }
+ break;
+ }
+ default:
+ if (HasAlpha()) {
+ m_pAlphaMask->MultiplyAlpha(alpha);
+ } else if (IsCmykImage()) {
+ if (!ConvertFormat((FXDIB_Format)(GetFormat() | 0x0200))) {
+ return FALSE;
+ }
+ m_pAlphaMask->MultiplyAlpha(alpha);
+ } else {
+ if (!ConvertFormat(FXDIB_Argb)) {
+ return FALSE;
+ }
+ MultiplyAlpha(alpha);
+ }
+ break;
+ }
+ return TRUE;
+}
+#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
+FX_DWORD CFX_DIBitmap::GetPixel(int x, int y) const
+{
+ if (m_pBuffer == NULL) {
+ return 0;
+ }
+ FX_LPBYTE pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8;
+ switch (GetFormat()) {
+ case FXDIB_1bppMask: {
+ if ((*pos) & (1 << (7 - x % 8))) {
+ return 0xff000000;
+ }
+ return 0;
+ }
+ case FXDIB_1bppRgb: {
+ if ((*pos) & (1 << (7 - x % 8))) {
+ return m_pPalette ? m_pPalette[1] : 0xffffffff;
+ } else {
+ return m_pPalette ? m_pPalette[0] : 0xff000000;
+ }
+ break;
+ }
+ case FXDIB_8bppMask:
+ return (*pos) << 24;
+ case FXDIB_8bppRgb:
+ return m_pPalette ? m_pPalette[*pos] : (0xff000000 | ((*pos) * 0x10101));
+ case FXDIB_Rgb:
+ case FXDIB_Rgba:
+ case FXDIB_Rgb32:
+ return FXARGB_GETDIB(pos) | 0xff000000;
+ case FXDIB_Argb:
+ return FXARGB_GETDIB(pos);
+ default:
+ break;
+ }
+ return 0;
+}
+#endif
+void CFX_DIBitmap::SetPixel(int x, int y, FX_DWORD color)
+{
+ if (m_pBuffer == NULL) {
+ return;
+ }
+ if (x < 0 || x >= m_Width || y < 0 || y >= m_Height) {
+ return;
+ }
+ FX_LPBYTE pos = m_pBuffer + y * m_Pitch + x * GetBPP() / 8;
+ switch (GetFormat()) {
+ case FXDIB_1bppMask:
+ if (color >> 24) {
+ *pos |= 1 << (7 - x % 8);
+ } else {
+ *pos &= ~(1 << (7 - x % 8));
+ }
+ break;
+ case FXDIB_1bppRgb:
+ if (m_pPalette) {
+ if (color == m_pPalette[1]) {
+ *pos |= 1 << (7 - x % 8);
+ } else {
+ *pos &= ~(1 << (7 - x % 8));
+ }
+ } else {
+ if (color == 0xffffffff) {
+ *pos |= 1 << (7 - x % 8);
+ } else {
+ *pos &= ~(1 << (7 - x % 8));
+ }
+ }
+ break;
+ case FXDIB_8bppMask:
+ *pos = (FX_BYTE)(color >> 24);
+ break;
+ case FXDIB_8bppRgb: {
+ if (m_pPalette) {
+ for (int i = 0; i < 256; i ++) {
+ if (m_pPalette[i] == color) {
+ *pos = (FX_BYTE)i;
+ return;
+ }
+ }
+ *pos = 0;
+ } else {
+ *pos = FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color));
+ }
+ break;
+ }
+ case FXDIB_Rgb:
+ case FXDIB_Rgb32: {
+ int alpha = FXARGB_A(color);
+ pos[0] = (FXARGB_B(color) * alpha + pos[0] * (255 - alpha)) / 255;
+ pos[1] = (FXARGB_G(color) * alpha + pos[1] * (255 - alpha)) / 255;
+ pos[2] = (FXARGB_R(color) * alpha + pos[2] * (255 - alpha)) / 255;
+ break;
+ }
+ case FXDIB_Rgba: {
+ pos[0] = FXARGB_B(color);
+ pos[1] = FXARGB_G(color);
+ pos[2] = FXARGB_R(color);
+ break;
+ }
+ case FXDIB_Argb:
+ FXARGB_SETDIB(pos, color);
+ break;
+ default:
+ break;
+ }
+}
+void CFX_DIBitmap::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_bpp,
+ int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const
+{
+ if (m_pBuffer == NULL) {
+ return;
+ }
+ int src_Bpp = m_bpp / 8;
+ FX_LPBYTE scanline = m_pBuffer + line * m_Pitch;
+ if (src_Bpp == 0) {
+ for (int i = 0; i < clip_width; i ++) {
+ FX_DWORD dest_x = clip_left + i;
+ FX_DWORD src_x = dest_x * m_Width / dest_width;
+ if (bFlipX) {
+ src_x = m_Width - src_x - 1;
+ }
+#ifdef FOXIT_CHROME_BUILD
+ src_x %= m_Width;
+#endif
+ dest_scan[i] = (scanline[src_x / 8] & (1 << (7 - src_x % 8))) ? 255 : 0;
+ }
+ } else if (src_Bpp == 1) {
+ for (int i = 0; i < clip_width; i ++) {
+ FX_DWORD dest_x = clip_left + i;
+ FX_DWORD src_x = dest_x * m_Width / dest_width;
+ if (bFlipX) {
+ src_x = m_Width - src_x - 1;
+ }
+#ifdef FOXIT_CHROME_BUILD
+ src_x %= m_Width;
+#endif
+ int dest_pos = i;
+ if (m_pPalette) {
+ if (!IsCmykImage()) {
+ dest_pos *= 3;
+ FX_ARGB argb = m_pPalette[scanline[src_x]];
+ dest_scan[dest_pos] = FXARGB_B(argb);
+ dest_scan[dest_pos + 1] = FXARGB_G(argb);
+ dest_scan[dest_pos + 2] = FXARGB_R(argb);
+ } else {
+ dest_pos *= 4;
+ FX_CMYK cmyk = m_pPalette[scanline[src_x]];
+ dest_scan[dest_pos] = FXSYS_GetCValue(cmyk);
+ dest_scan[dest_pos + 1] = FXSYS_GetMValue(cmyk);
+ dest_scan[dest_pos + 2] = FXSYS_GetYValue(cmyk);
+ dest_scan[dest_pos + 3] = FXSYS_GetKValue(cmyk);
+ }
+ } else {
+ dest_scan[dest_pos] = scanline[src_x];
+ }
+ }
+ } else {
+ for (int i = 0; i < clip_width; i ++) {
+ FX_DWORD dest_x = clip_left + i;
+ FX_DWORD src_x = bFlipX ? (m_Width - dest_x * m_Width / dest_width - 1) * src_Bpp : (dest_x * m_Width / dest_width) * src_Bpp;
+#ifdef FOXIT_CHROME_BUILD
+ src_x %= m_Width * src_Bpp;
+#endif
+ int dest_pos = i * src_Bpp;
+ for (int b = 0; b < src_Bpp; b ++) {
+ dest_scan[dest_pos + b] = scanline[src_x + b];
+ }
+ }
+ }
+}
+FX_BOOL CFX_DIBitmap::ConvertColorScale(FX_DWORD forecolor, FX_DWORD backcolor)
+{
+ ASSERT(!IsAlphaMask());
+ if (m_pBuffer == NULL || IsAlphaMask()) {
+ return FALSE;
+ }
+ int fc, fm, fy, fk, bc, bm, by, bk;
+ int fr, fg, fb, br, bg, bb;
+ FX_BOOL isCmykImage = IsCmykImage();
+ if (isCmykImage) {
+ fc = FXSYS_GetCValue(forecolor);
+ fm = FXSYS_GetMValue(forecolor);
+ fy = FXSYS_GetYValue(forecolor);
+ fk = FXSYS_GetKValue(forecolor);
+ bc = FXSYS_GetCValue(backcolor);
+ bm = FXSYS_GetMValue(backcolor);
+ by = FXSYS_GetYValue(backcolor);
+ bk = FXSYS_GetKValue(backcolor);
+ } else {
+ fr = FXSYS_GetRValue(forecolor);
+ fg = FXSYS_GetGValue(forecolor);
+ fb = FXSYS_GetBValue(forecolor);
+ br = FXSYS_GetRValue(backcolor);
+ bg = FXSYS_GetGValue(backcolor);
+ bb = FXSYS_GetBValue(backcolor);
+ }
+ if (m_bpp <= 8) {
+ if (isCmykImage) {
+ if (forecolor == 0xff && backcolor == 0 && m_pPalette == NULL) {
+ return TRUE;
+ }
+ } else if (forecolor == 0 && backcolor == 0xffffff && m_pPalette == NULL) {
+ return TRUE;
+ }
+ if (m_pPalette == NULL) {
+ BuildPalette();
+ }
+ int size = 1 << m_bpp;
+ if (isCmykImage) {
+ for (int i = 0; i < size; i ++) {
+ FX_BYTE b, g, r;
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(m_pPalette[i]), FXSYS_GetMValue(m_pPalette[i]), FXSYS_GetYValue(m_pPalette[i]), FXSYS_GetKValue(m_pPalette[i]),
+ r, g, b);
+ int gray = 255 - FXRGB2GRAY(r, g, b);
+ m_pPalette[i] = CmykEncode(bc + (fc - bc) * gray / 255, bm + (fm - bm) * gray / 255,
+ by + (fy - by) * gray / 255, bk + (fk - bk) * gray / 255);
+ }
+ } else
+ for (int i = 0; i < size; i ++) {
+ int gray = FXRGB2GRAY(FXARGB_R(m_pPalette[i]), FXARGB_G(m_pPalette[i]), FXARGB_B(m_pPalette[i]));
+ m_pPalette[i] = FXARGB_MAKE(0xff, br + (fr - br) * gray / 255, bg + (fg - bg) * gray / 255,
+ bb + (fb - bb) * gray / 255);
+ }
+ return TRUE;
+ }
+ if (isCmykImage) {
+ if (forecolor == 0xff && backcolor == 0x00) {
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE scanline = m_pBuffer + row * m_Pitch;
+ for (int col = 0; col < m_Width; col ++) {
+ FX_BYTE b, g, r;
+ AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3],
+ r, g, b);
+ *scanline ++ = 0;
+ *scanline ++ = 0;
+ *scanline ++ = 0;
+ *scanline ++ = 255 - FXRGB2GRAY(r, g, b);
+ }
+ }
+ return TRUE;
+ }
+ } else if (forecolor == 0 && backcolor == 0xffffff) {
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE scanline = m_pBuffer + row * m_Pitch;
+ int gap = m_bpp / 8 - 2;
+ for (int col = 0; col < m_Width; col ++) {
+ int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]);
+ *scanline ++ = gray;
+ *scanline ++ = gray;
+ *scanline = gray;
+ scanline += gap;
+ }
+ }
+ return TRUE;
+ }
+ if (isCmykImage) {
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE scanline = m_pBuffer + row * m_Pitch;
+ for (int col = 0; col < m_Width; col ++) {
+ FX_BYTE b, g, r;
+ AdobeCMYK_to_sRGB1(scanline[0], scanline[1], scanline[2], scanline[3],
+ r, g, b);
+ int gray = 255 - FXRGB2GRAY(r, g, b);
+ *scanline ++ = bc + (fc - bc) * gray / 255;
+ *scanline ++ = bm + (fm - bm) * gray / 255;
+ *scanline ++ = by + (fy - by) * gray / 255;
+ *scanline ++ = bk + (fk - bk) * gray / 255;
+ }
+ }
+ } else
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPBYTE scanline = m_pBuffer + row * m_Pitch;
+ int gap = m_bpp / 8 - 2;
+ for (int col = 0; col < m_Width; col ++) {
+ int gray = FXRGB2GRAY(scanline[2], scanline[1], scanline[0]);
+ *scanline ++ = bb + (fb - bb) * gray / 255;
+ *scanline ++ = bg + (fg - bg) * gray / 255;
+ *scanline = br + (fr - br) * gray / 255;
+ scanline += gap;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CFX_DIBitmap::DitherFS(const FX_DWORD* pPalette, int pal_size, const FX_RECT* pRect)
+{
+ if (m_pBuffer == NULL) {
+ return FALSE;
+ }
+ if (m_bpp != 8 && m_pPalette != NULL && m_AlphaFlag != 0) {
+ return FALSE;
+ }
+ if (m_Width < 4 && m_Height < 4) {
+ return FALSE;
+ }
+ FX_RECT rect(0, 0, m_Width, m_Height);
+ if (pRect) {
+ rect.Intersect(*pRect);
+ }
+ FX_BYTE translate[256];
+ for (int i = 0; i < 256; i ++) {
+ int err2 = 65536;
+ for (int j = 0; j < pal_size; j ++) {
+ FX_BYTE entry = (FX_BYTE)pPalette[j];
+ int err = (int)entry - i;
+ if (err * err < err2) {
+ err2 = err * err;
+ translate[i] = entry;
+ }
+ }
+ }
+ for (int row = rect.top; row < rect.bottom; row ++) {
+ FX_LPBYTE scan = m_pBuffer + row * m_Pitch;
+ FX_LPBYTE next_scan = m_pBuffer + (row + 1) * m_Pitch;
+ for (int col = rect.left; col < rect.right; col ++) {
+ int src_pixel = scan[col];
+ int dest_pixel = translate[src_pixel];
+ scan[col] = (FX_BYTE)dest_pixel;
+ int error = -dest_pixel + src_pixel;
+ if (col < rect.right - 1) {
+ int src = scan[col + 1];
+ src += error * 7 / 16;
+ if (src > 255) {
+ scan[col + 1] = 255;
+ } else if (src < 0) {
+ scan[col + 1] = 0;
+ } else {
+ scan[col + 1] = src;
+ }
+ }
+ if (col < rect.right - 1 && row < rect.bottom - 1) {
+ int src = next_scan[col + 1];
+ src += error * 1 / 16;
+ if (src > 255) {
+ next_scan[col + 1] = 255;
+ } else if (src < 0) {
+ next_scan[col + 1] = 0;
+ } else {
+ next_scan[col + 1] = src;
+ }
+ }
+ if (row < rect.bottom - 1) {
+ int src = next_scan[col];
+ src += error * 5 / 16;
+ if (src > 255) {
+ next_scan[col] = 255;
+ } else if (src < 0) {
+ next_scan[col] = 0;
+ } else {
+ next_scan[col] = src;
+ }
+ }
+ if (col > rect.left && row < rect.bottom - 1) {
+ int src = next_scan[col - 1];
+ src += error * 3 / 16;
+ if (src > 255) {
+ next_scan[col - 1] = 255;
+ } else if (src < 0) {
+ next_scan[col - 1] = 0;
+ } else {
+ next_scan[col - 1] = src;
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+CFX_DIBitmap* CFX_DIBSource::FlipImage(FX_BOOL bXFlip, FX_BOOL bYFlip) const
+{
+ CFX_DIBitmap* pFlipped = FX_NEW CFX_DIBitmap;
+ if (!pFlipped) {
+ return NULL;
+ }
+ if (!pFlipped->Create(m_Width, m_Height, GetFormat())) {
+ delete pFlipped;
+ return NULL;
+ }
+ pFlipped->CopyPalette(m_pPalette);
+ FX_LPBYTE pDestBuffer = pFlipped->GetBuffer();
+ int Bpp = m_bpp / 8;
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPCBYTE src_scan = GetScanline(row);
+ FX_LPBYTE dest_scan = pDestBuffer + m_Pitch * (bYFlip ? (m_Height - row - 1) : row);
+ if (!bXFlip) {
+ FXSYS_memcpy32(dest_scan, src_scan, m_Pitch);
+ continue;
+ }
+ if (m_bpp == 1) {
+ FXSYS_memset32(dest_scan, 0, m_Pitch);
+ for (int col = 0; col < m_Width; col ++)
+ if (src_scan[col / 8] & (1 << (7 - col % 8))) {
+ int dest_col = m_Width - col - 1;
+ dest_scan[dest_col / 8] |= (1 << (7 - dest_col % 8));
+ }
+ } else {
+ dest_scan += (m_Width - 1) * Bpp;
+ if (Bpp == 1) {
+ for (int col = 0; col < m_Width; col ++) {
+ *dest_scan = *src_scan;
+ dest_scan --;
+ src_scan ++;
+ }
+ } else if (Bpp == 3) {
+ for (int col = 0; col < m_Width; col ++) {
+ dest_scan[0] = src_scan[0];
+ dest_scan[1] = src_scan[1];
+ dest_scan[2] = src_scan[2];
+ dest_scan -= 3;
+ src_scan += 3;
+ }
+ } else {
+ ASSERT(Bpp == 4);
+ for (int col = 0; col < m_Width; col ++) {
+ *(FX_DWORD*)dest_scan = *(FX_DWORD*)src_scan;
+ dest_scan -= 4;
+ src_scan += 4;
+ }
+ }
+ }
+ }
+ if (m_pAlphaMask) {
+ pDestBuffer = pFlipped->m_pAlphaMask->GetBuffer();
+ FX_DWORD dest_pitch = pFlipped->m_pAlphaMask->GetPitch();
+ for (int row = 0; row < m_Height; row ++) {
+ FX_LPCBYTE src_scan = m_pAlphaMask->GetScanline(row);
+ FX_LPBYTE dest_scan = pDestBuffer + dest_pitch * (bYFlip ? (m_Height - row - 1) : row);
+ if (!bXFlip) {
+ FXSYS_memcpy32(dest_scan, src_scan, dest_pitch);
+ continue;
+ }
+ dest_scan += (m_Width - 1);
+ for (int col = 0; col < m_Width; col ++) {
+ *dest_scan = *src_scan;
+ dest_scan --;
+ src_scan ++;
+ }
+ }
+ }
+ return pFlipped;
+}
+CFX_DIBExtractor::CFX_DIBExtractor(const CFX_DIBSource* pSrc)
+{
+ m_pBitmap = NULL;
+ if (pSrc->GetBuffer() == NULL) {
+ m_pBitmap = pSrc->Clone();
+ } else {
+ m_pBitmap = FX_NEW CFX_DIBitmap;
+ if (!m_pBitmap) {
+ return;
+ }
+ if (!m_pBitmap->Create(pSrc->GetWidth(), pSrc->GetHeight(), pSrc->GetFormat(), pSrc->GetBuffer())) {
+ delete m_pBitmap;
+ m_pBitmap = NULL;
+ return;
+ }
+ m_pBitmap->CopyPalette(pSrc->GetPalette());
+ m_pBitmap->CopyAlphaMask(pSrc->m_pAlphaMask);
+ }
+}
+CFX_DIBExtractor::~CFX_DIBExtractor()
+{
+ if (m_pBitmap) {
+ delete m_pBitmap;
+ }
+}
+CFX_FilteredDIB::CFX_FilteredDIB()
+{
+ m_pScanline = NULL;
+ m_pSrc = NULL;
+}
+CFX_FilteredDIB::~CFX_FilteredDIB()
+{
+ if (m_pSrc && m_bAutoDropSrc) {
+ delete m_pSrc;
+ }
+ if (m_pScanline) {
+ FX_Free(m_pScanline);
+ }
+}
+void CFX_FilteredDIB::LoadSrc(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc)
+{
+ m_pSrc = pSrc;
+ m_bAutoDropSrc = bAutoDropSrc;
+ m_Width = pSrc->GetWidth();
+ m_Height = pSrc->GetHeight();
+ FXDIB_Format format = GetDestFormat();
+ m_bpp = (FX_BYTE)format;
+ m_AlphaFlag = (FX_BYTE)(format >> 8);
+ m_Pitch = (m_Width * (format & 0xff) + 31) / 32 * 4;
+ m_pPalette = GetDestPalette();
+ m_pScanline = FX_Alloc(FX_BYTE, m_Pitch);
+}
+FX_LPCBYTE CFX_FilteredDIB::GetScanline(int line) const
+{
+ TranslateScanline(m_pScanline, m_pSrc->GetScanline(line));
+ return m_pScanline;
+}
+void CFX_FilteredDIB::DownSampleScanline(int line, FX_LPBYTE dest_scan, int dest_bpp,
+ int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const
+{
+ m_pSrc->DownSampleScanline(line, dest_scan, dest_bpp, dest_width, bFlipX, clip_left, clip_width);
+ TranslateDownSamples(dest_scan, dest_scan, clip_width, dest_bpp);
+}
+CFX_ImageRenderer::CFX_ImageRenderer()
+{
+ m_Status = 0;
+ m_pTransformer = NULL;
+ m_bRgbByteOrder = FALSE;
+ m_BlendType = FXDIB_BLEND_NORMAL;
+}
+CFX_ImageRenderer::~CFX_ImageRenderer()
+{
+ if (m_pTransformer) {
+ delete m_pTransformer;
+ }
+}
+extern FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, int width, int height, FX_BOOL bFlipX, FX_BOOL bFlipY);
+FX_BOOL CFX_ImageRenderer::Start(CFX_DIBitmap* pDevice, const CFX_ClipRgn* pClipRgn,
+ const CFX_DIBSource* pSource, int bitmap_alpha,
+ FX_DWORD mask_color, const CFX_AffineMatrix* pMatrix,
+ FX_DWORD dib_flags, FX_BOOL bRgbByteOrder,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ m_Matrix = *pMatrix;
+ CFX_FloatRect image_rect_f = m_Matrix.GetUnitRect();
+ FX_RECT image_rect = image_rect_f.GetOutterRect();
+ m_ClipBox = pClipRgn ? pClipRgn->GetBox() : FX_RECT(0, 0, pDevice->GetWidth(), pDevice->GetHeight());
+ m_ClipBox.Intersect(image_rect);
+ if (m_ClipBox.IsEmpty()) {
+ return FALSE;
+ }
+ m_pDevice = pDevice;
+ m_pClipRgn = pClipRgn;
+ m_MaskColor = mask_color;
+ m_BitmapAlpha = bitmap_alpha;
+ m_Matrix = *pMatrix;
+ m_Flags = dib_flags;
+ m_AlphaFlag = alpha_flag;
+ m_pIccTransform = pIccTransform;
+ m_bRgbByteOrder = bRgbByteOrder;
+ m_BlendType = blend_type;
+ FX_BOOL ret = TRUE;
+ if ((FXSYS_fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) ||
+ (FXSYS_fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0) ) {
+ if (FXSYS_fabs(m_Matrix.a) < FXSYS_fabs(m_Matrix.b) / 20 && FXSYS_fabs(m_Matrix.d) < FXSYS_fabs(m_Matrix.c) / 20 &&
+ FXSYS_fabs(m_Matrix.a) < 0.5f && FXSYS_fabs(m_Matrix.d) < 0.5f) {
+ int dest_width = image_rect.Width();
+ int dest_height = image_rect.Height();
+ FX_RECT bitmap_clip = m_ClipBox;
+ bitmap_clip.Offset(-image_rect.left, -image_rect.top);
+ bitmap_clip = _FXDIB_SwapClipBox(bitmap_clip, dest_width, dest_height, m_Matrix.c > 0, m_Matrix.b < 0);
+ m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox, TRUE,
+ m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder, alpha_flag, pIccTransform, m_BlendType);
+ if (!m_Stretcher.Start(&m_Composer, pSource, dest_height, dest_width, bitmap_clip, dib_flags)) {
+ return FALSE;
+ }
+ m_Status = 1;
+ return TRUE;
+ }
+ m_Status = 2;
+ m_pTransformer = FX_NEW CFX_ImageTransformer;
+ if (!m_pTransformer) {
+ return FALSE;
+ }
+ m_pTransformer->Start(pSource, &m_Matrix, dib_flags, &m_ClipBox);
+ return TRUE;
+ }
+ int dest_width = image_rect.Width();
+ if (m_Matrix.a < 0) {
+ dest_width = -dest_width;
+ }
+ int dest_height = image_rect.Height();
+ if (m_Matrix.d > 0) {
+ dest_height = -dest_height;
+ }
+ if (dest_width == 0 || dest_height == 0) {
+ return FALSE;
+ }
+ FX_RECT bitmap_clip = m_ClipBox;
+ bitmap_clip.Offset(-image_rect.left, -image_rect.top);
+ m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color,
+ m_ClipBox, FALSE, FALSE, FALSE, m_bRgbByteOrder, alpha_flag, pIccTransform, m_BlendType);
+ m_Status = 1;
+ ret = m_Stretcher.Start(&m_Composer, pSource, dest_width, dest_height, bitmap_clip, dib_flags);
+ return ret;
+}
+FX_BOOL CFX_ImageRenderer::Continue(IFX_Pause* pPause)
+{
+ if (m_Status == 1) {
+ return m_Stretcher.Continue(pPause);
+ } else if (m_Status == 2) {
+ if (m_pTransformer->Continue(pPause)) {
+ return TRUE;
+ }
+ CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach();
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ if (pBitmap->GetBuffer() == NULL) {
+ delete pBitmap;
+ return FALSE;
+ }
+ if (pBitmap->IsAlphaMask()) {
+ if (m_BitmapAlpha != 255) {
+ if (m_AlphaFlag >> 8) {
+ m_AlphaFlag = (((FX_BYTE)((m_AlphaFlag & 0xff) * m_BitmapAlpha / 255)) | ((m_AlphaFlag >> 8) << 8));
+ } else {
+ m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, m_BitmapAlpha);
+ }
+ }
+ m_pDevice->CompositeMask(m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop,
+ pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, m_MaskColor,
+ 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform);
+ } else {
+ if (m_BitmapAlpha != 255) {
+ pBitmap->MultiplyAlpha(m_BitmapAlpha);
+ }
+ m_pDevice->CompositeBitmap(m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop,
+ pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, 0, 0, m_BlendType, m_pClipRgn, m_bRgbByteOrder, m_pIccTransform);
+ }
+ delete pBitmap;
+ return FALSE;
+ }
+ return FALSE;
+}
+CFX_BitmapStorer::CFX_BitmapStorer()
+{
+ m_pBitmap = NULL;
+}
+CFX_BitmapStorer::~CFX_BitmapStorer()
+{
+ if (m_pBitmap) {
+ delete m_pBitmap;
+ }
+}
+CFX_DIBitmap* CFX_BitmapStorer::Detach()
+{
+ CFX_DIBitmap* pBitmap = m_pBitmap;
+ m_pBitmap = NULL;
+ return pBitmap;
+}
+void CFX_BitmapStorer::Replace(CFX_DIBitmap* pBitmap)
+{
+ if (m_pBitmap) {
+ delete m_pBitmap;
+ }
+ m_pBitmap = pBitmap;
+}
+void CFX_BitmapStorer::ComposeScanline(int line, FX_LPCBYTE scanline, FX_LPCBYTE scan_extra_alpha)
+{
+ FX_LPBYTE dest_buf = (FX_LPBYTE)m_pBitmap->GetScanline(line);
+ FX_LPBYTE dest_alpha_buf = m_pBitmap->m_pAlphaMask ?
+ (FX_LPBYTE)m_pBitmap->m_pAlphaMask->GetScanline(line) : NULL;
+ if (dest_buf) {
+ FXSYS_memcpy32(dest_buf, scanline, m_pBitmap->GetPitch());
+ }
+ if (dest_alpha_buf) {
+ FXSYS_memcpy32(dest_alpha_buf, scan_extra_alpha, m_pBitmap->m_pAlphaMask->GetPitch());
+ }
+}
+FX_BOOL CFX_BitmapStorer::SetInfo(int width, int height, FXDIB_Format src_format, FX_DWORD* pSrcPalette)
+{
+ m_pBitmap = FX_NEW CFX_DIBitmap;
+ if (!m_pBitmap) {
+ return FALSE;
+ }
+ if (!m_pBitmap->Create(width, height, src_format)) {
+ delete m_pBitmap;
+ m_pBitmap = NULL;
+ return FALSE;
+ }
+ if (pSrcPalette) {
+ m_pBitmap->CopyPalette(pSrcPalette);
+ }
+ return TRUE;
+}
diff --git a/core/src/fxge/dib/fx_dib_transform.cpp b/core/src/fxge/dib/fx_dib_transform.cpp
index 4d83005161..80475cbb1f 100644
--- a/core/src/fxge/dib/fx_dib_transform.cpp
+++ b/core/src/fxge/dib/fx_dib_transform.cpp
@@ -1,797 +1,797 @@
-// 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 "../../../include/fxge/fx_dib.h"
-#include "dib_int.h"
-int SDP_Table[513] = {
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254,
- 253, 253, 253, 252, 252, 252, 251, 251, 251, 250, 250, 249, 249, 249, 248, 248, 247, 247, 246,
- 246, 245, 244, 244, 243, 243, 242, 242, 241, 240, 240, 239, 238, 238, 237, 236, 236, 235, 234,
- 233, 233, 232, 231, 230, 230, 229, 228, 227, 226, 226, 225, 224, 223, 222, 221, 220, 219, 218,
- 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200,
- 199, 198, 196, 195, 194, 193, 192, 191, 190, 189, 188, 186, 185, 184, 183, 182, 181, 179, 178,
- 177, 176, 175, 173, 172, 171, 170, 169, 167, 166, 165, 164, 162, 161, 160, 159, 157, 156, 155,
- 154, 152, 151, 150, 149, 147, 146, 145, 143, 142, 141, 140, 138, 137, 136, 134, 133, 132, 130,
- 129, 128, 126, 125, 124, 122, 121, 120, 119, 117, 116, 115, 113, 112, 111, 109, 108, 107, 105,
- 104, 103, 101, 100, 99, 97, 96, 95, 93, 92, 91, 89, 88, 87, 85, 84, 83, 81, 80, 79, 77, 76, 75,
- 73, 72, 71, 69, 68, 67, 66, 64, 63, 62, 60, 59, 58, 57, 55, 54, 53, 52, 50, 49, 48, 47, 45, 44,
- 43, 42, 40, 39, 38, 37, 36, 34, 33, 32, 31, 30, 28, 27, 26, 25, 24, 23, 21, 20, 19, 18, 17, 16,
- 15, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5, -6, -7, -7, -8, -9, -10,
- -11, -12, -12, -13, -14, -15, -15, -16, -17, -17, -18, -19, -19, -20, -21, -21, -22, -22, -23, -24,
- -24, -25, -25, -26, -26, -27, -27, -27, -28, -28, -29, -29, -30, -30, -30, -31, -31, -31, -32, -32,
- -32, -33, -33, -33, -33, -34, -34, -34, -34, -35, -35, -35, -35, -35, -36, -36, -36, -36, -36, -36,
- -36, -36, -36, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
- -37, -37, -37, -37, -36, -36, -36, -36, -36, -36, -36, -36, -36, -35, -35, -35, -35, -35, -35, -34,
- -34, -34, -34, -34, -33, -33, -33, -33, -33, -32, -32, -32, -32, -31, -31, -31, -31, -30, -30, -30,
- -30, -29, -29, -29, -29, -28, -28, -28, -27, -27, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24,
- -24, -23, -23, -23, -22, -22, -22, -22, -21, -21, -21, -20, -20, -20, -19, -19, -19, -18, -18, -18,
- -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -12, -11, -11,
- -11, -10, -10, -10, -9, -9, -9, -9, -8, -8, -8, -7, -7, -7, -7, -6, -6, -6, -6, -5, -5, -5, -5, -4,
- -4, -4, -4, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-class CFX_BilinearMatrix : public CPDF_FixedMatrix
-{
-public:
- CFX_BilinearMatrix(const CFX_AffineMatrix& src, int bits): CPDF_FixedMatrix(src, bits)
- {}
- inline void Transform(int x, int y, int& x1, int& y1, int&res_x, int&res_y)
- {
- x1 = a * x + c * y + e + base / 2;
- y1 = b * x + d * y + f + base / 2;
- res_x = x1 % base;
- res_y = y1 % base;
- if (res_x < 0 && res_x > -base) {
- res_x = base + res_x;
- }
- if (res_y < 0 && res_x > -base) {
- res_y = base + res_y;
- }
- x1 /= base;
- y1 /= base;
- }
-};
-CFX_DIBitmap* CFX_DIBSource::SwapXY(FX_BOOL bXFlip, FX_BOOL bYFlip, const FX_RECT* pDestClip) const
-{
- FX_RECT dest_clip(0, 0, m_Height, m_Width);
- if (pDestClip) {
- dest_clip.Intersect(*pDestClip);
- }
- if (dest_clip.IsEmpty()) {
- return NULL;
- }
- CFX_DIBitmap* pTransBitmap = FX_NEW CFX_DIBitmap;
- if (!pTransBitmap) {
- return NULL;
- }
- int result_height = dest_clip.Height(), result_width = dest_clip.Width();
- if (!pTransBitmap->Create(result_width, result_height, GetFormat())) {
- delete pTransBitmap;
- return NULL;
- }
- pTransBitmap->CopyPalette(m_pPalette);
- int src_pitch = m_Pitch;
- int dest_pitch = pTransBitmap->GetPitch();
- FX_LPBYTE dest_buf = pTransBitmap->GetBuffer();
- int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left;
- int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right;
- int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top;
- int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom;
- if (GetBPP() == 1) {
- FXSYS_memset8(dest_buf, 0xff, dest_pitch * result_height);
- for (int row = row_start; row < row_end; row ++) {
- FX_LPCBYTE src_scan = GetScanline(row);
- int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left;
- FX_LPBYTE dest_scan = dest_buf;
- if (bYFlip) {
- dest_scan += (result_height - 1) * dest_pitch;
- }
- int dest_step = bYFlip ? -dest_pitch : dest_pitch;
- for (int col = col_start; col < col_end; col ++) {
- if (!(src_scan[col / 8] & (1 << (7 - col % 8)))) {
- dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8));
- }
- dest_scan += dest_step;
- }
- }
- } else {
- int nBytes = GetBPP() / 8;
- int dest_step = bYFlip ? -dest_pitch : dest_pitch;
- if (nBytes == 3) {
- dest_step -= 2;
- }
- for (int row = row_start; row < row_end; row ++) {
- int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left;
- FX_LPBYTE dest_scan = dest_buf + dest_col * nBytes;
- if (bYFlip) {
- dest_scan += (result_height - 1) * dest_pitch;
- }
- if (nBytes == 4) {
- FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + col_start;
- for (int col = col_start; col < col_end; col ++) {
- *(FX_DWORD*)dest_scan = *src_scan++;
- dest_scan += dest_step;
- }
- } else {
- FX_LPCBYTE src_scan = GetScanline(row) + col_start * nBytes;
- if (nBytes == 1)
- for (int col = col_start; col < col_end; col ++) {
- *dest_scan = *src_scan++;
- dest_scan += dest_step;
- }
- else
- for (int col = col_start; col < col_end; col ++) {
- *dest_scan++ = *src_scan++;
- *dest_scan++ = *src_scan++;
- *dest_scan = *src_scan++;
- dest_scan += dest_step;
- }
- }
- }
- }
- if (m_pAlphaMask) {
- src_pitch = m_pAlphaMask->m_Pitch;
- dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch();
- dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer();
- int dest_step = bYFlip ? -dest_pitch : dest_pitch;
- for (int row = row_start; row < row_end; row ++) {
- int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left;
- FX_LPBYTE dest_scan = dest_buf + dest_col;
- if (bYFlip) {
- dest_scan += (result_height - 1) * dest_pitch;
- }
- FX_LPCBYTE src_scan = m_pAlphaMask->GetScanline(row) + col_start;
- for (int col = col_start; col < col_end; col ++) {
- *dest_scan = *src_scan++;
- dest_scan += dest_step;
- }
- }
- }
- return pTransBitmap;
-}
-#define FIX16_005 0.05f
-FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, int width, int height, FX_BOOL bFlipX, FX_BOOL bFlipY)
-{
- FX_RECT rect;
- if (bFlipY) {
- rect.left = height - clip.top;
- rect.right = height - clip.bottom;
- } else {
- rect.left = clip.top;
- rect.right = clip.bottom;
- }
- if (bFlipX) {
- rect.top = width - clip.left;
- rect.bottom = width - clip.right;
- } else {
- rect.top = clip.left;
- rect.bottom = clip.right;
- }
- rect.Normalize();
- return rect;
-}
-CFX_DIBitmap* CFX_DIBSource::TransformTo(const CFX_AffineMatrix* pDestMatrix, int& result_left, int& result_top,
- FX_DWORD flags, const FX_RECT* pDestClip) const
-{
- CFX_ImageTransformer transformer;
- transformer.Start(this, pDestMatrix, flags, pDestClip);
- transformer.Continue(NULL);
- result_left = transformer.m_ResultLeft;
- result_top = transformer.m_ResultTop;
- CFX_DIBitmap* pTransformed = transformer.m_Storer.Detach();
- return pTransformed;
-}
-CFX_DIBitmap* CFX_DIBSource::StretchTo(int dest_width, int dest_height, FX_DWORD flags, const FX_RECT* pClip) const
-{
- FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height));
- if (pClip) {
- clip_rect.Intersect(*pClip);
- }
- if (clip_rect.IsEmpty()) {
- return NULL;
- }
- if (dest_width == m_Width && dest_height == m_Height) {
- return Clone(&clip_rect);
- }
- CFX_ImageStretcher stretcher;
- CFX_BitmapStorer storer;
- if (stretcher.Start(&storer, this, dest_width, dest_height, clip_rect, flags)) {
- stretcher.Continue(NULL);
- }
- return storer.Detach();
-}
-CFX_ImageTransformer::CFX_ImageTransformer()
-{
- m_Status = 0;
- m_pMatrix = NULL;
-}
-CFX_ImageTransformer::~CFX_ImageTransformer()
-{
-}
-FX_BOOL CFX_ImageTransformer::Start(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix, int flags, const FX_RECT* pDestClip)
-{
- m_pMatrix = (CFX_AffineMatrix*)pDestMatrix;
- CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect();
- FX_RECT result_rect = unit_rect.GetClosestRect();
- FX_RECT result_clip = result_rect;
- if (pDestClip) {
- result_clip.Intersect(*pDestClip);
- }
- if (result_clip.IsEmpty()) {
- return FALSE;
- }
- m_ResultLeft = result_clip.left;
- m_ResultTop = result_clip.top;
- m_ResultWidth = result_clip.Width();
- m_ResultHeight = result_clip.Height();
- m_Flags = flags;
- if (FXSYS_fabs(pDestMatrix->a) < FXSYS_fabs(pDestMatrix->b) / 20 &&
- FXSYS_fabs(pDestMatrix->d) < FXSYS_fabs(pDestMatrix->c) / 20 &&
- FXSYS_fabs(pDestMatrix->a) < 0.5f && FXSYS_fabs(pDestMatrix->d) < 0.5f) {
- int dest_width = result_rect.Width();
- int dest_height = result_rect.Height();
- result_clip.Offset(-result_rect.left, -result_rect.top);
- result_clip = _FXDIB_SwapClipBox(result_clip, dest_width, dest_height, pDestMatrix->c > 0, pDestMatrix->b < 0);
- m_Stretcher.Start(&m_Storer, pSrc, dest_height, dest_width, result_clip, flags);
- m_Status = 1;
- return TRUE;
- }
- if (FXSYS_fabs(pDestMatrix->b) < FIX16_005 && FXSYS_fabs(pDestMatrix->c) < FIX16_005) {
- int dest_width = pDestMatrix->a > 0 ? (int)FXSYS_ceil(pDestMatrix->a) : (int)FXSYS_floor(pDestMatrix->a);
- int dest_height = pDestMatrix->d > 0 ? (int) - FXSYS_ceil(pDestMatrix->d) : (int) - FXSYS_floor(pDestMatrix->d);
- result_clip.Offset(-result_rect.left, -result_rect.top);
- m_Stretcher.Start(&m_Storer, pSrc, dest_width, dest_height, result_clip, flags);
- m_Status = 2;
- return TRUE;
- }
- int stretch_width = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->a, pDestMatrix->b));
- int stretch_height = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->c, pDestMatrix->d));
- CFX_AffineMatrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, (FX_FLOAT)(stretch_height));
- stretch2dest.Concat(pDestMatrix->a / stretch_width, pDestMatrix->b / stretch_width,
- pDestMatrix->c / stretch_height, pDestMatrix->d / stretch_height, pDestMatrix->e, pDestMatrix->f);
- m_dest2stretch.SetReverse(stretch2dest);
- CFX_FloatRect clip_rect_f(result_clip);
- clip_rect_f.Transform(&m_dest2stretch);
- m_StretchClip = clip_rect_f.GetOutterRect();
- m_StretchClip.Intersect(0, 0, stretch_width, stretch_height);
- m_Stretcher.Start(&m_Storer, pSrc, stretch_width, stretch_height, m_StretchClip, flags);
- m_Status = 3;
- return TRUE;
-}
-FX_BYTE _bilinear_interpol(FX_LPCBYTE buf, int row_offset_l, int row_offset_r,
- int src_col_l, int src_col_r, int res_x, int res_y,
- int bpp, int c_offset)
-{
- int i_resx = 255 - res_x;
- int col_bpp_l = src_col_l * bpp;
- int col_bpp_r = src_col_r * bpp;
- FX_LPCBYTE buf_u = buf + row_offset_l + c_offset;
- FX_LPCBYTE buf_d = buf + row_offset_r + c_offset;
- FX_LPCBYTE src_pos0 = buf_u + col_bpp_l;
- FX_LPCBYTE src_pos1 = buf_u + col_bpp_r;
- FX_LPCBYTE src_pos2 = buf_d + col_bpp_l;
- FX_LPCBYTE src_pos3 = buf_d + col_bpp_r;
- FX_BYTE r_pos_0 = (*src_pos0 * i_resx + *src_pos1 * res_x) >> 8;
- FX_BYTE r_pos_1 = (*src_pos2 * i_resx + *src_pos3 * res_x) >> 8;
- return (r_pos_0 * (255 - res_y) + r_pos_1 * res_y) >> 8;
-}
-FX_BYTE _bicubic_interpol(FX_LPCBYTE buf, int pitch, int pos_pixel[], int u_w[], int v_w[], int res_x, int res_y,
- int bpp, int c_offset)
-{
- int s_result = 0;
- for (int i = 0; i < 4; i ++) {
- int a_result = 0;
- for (int j = 0; j < 4; j ++) {
- a_result += u_w[j] * (*(FX_BYTE*)(buf + pos_pixel[i + 4] * pitch + pos_pixel[j] * bpp + c_offset));
- }
- s_result += a_result * v_w[i];
- }
- s_result >>= 16;
- return (FX_BYTE)(s_result < 0 ? 0 : s_result > 255 ? 255 : s_result);
-}
-void _bicubic_get_pos_weight(int pos_pixel[], int u_w[], int v_w[], int src_col_l, int src_row_l,
- int res_x, int res_y, int stretch_width, int stretch_height)
-{
- pos_pixel[0] = src_col_l - 1;
- pos_pixel[1] = src_col_l;
- pos_pixel[2] = src_col_l + 1;
- pos_pixel[3] = src_col_l + 2;
- pos_pixel[4] = src_row_l - 1;
- pos_pixel[5] = src_row_l;
- pos_pixel[6] = src_row_l + 1;
- pos_pixel[7] = src_row_l + 2;
- for (int i = 0 ; i < 4; i ++) {
- if (pos_pixel[i] < 0) {
- pos_pixel[i] = 0;
- }
- if (pos_pixel[i] >= stretch_width) {
- pos_pixel[i] = stretch_width - 1;
- }
- if (pos_pixel[i + 4] < 0) {
- pos_pixel[i + 4] = 0;
- }
- if (pos_pixel[i + 4] >= stretch_height) {
- pos_pixel[i + 4] = stretch_height - 1;
- }
- }
- u_w[0] = SDP_Table[256 + res_x];
- u_w[1] = SDP_Table[res_x];
- u_w[2] = SDP_Table[256 - res_x];
- u_w[3] = SDP_Table[512 - res_x];
- v_w[0] = SDP_Table[256 + res_y];
- v_w[1] = SDP_Table[res_y];
- v_w[2] = SDP_Table[256 - res_y];
- v_w[3] = SDP_Table[512 - res_y];
-}
-FXDIB_Format _GetTransformedFormat(const CFX_DIBSource* pDrc)
-{
- FXDIB_Format format = pDrc->GetFormat();
- if (pDrc->IsAlphaMask()) {
- format = FXDIB_8bppMask;
- } else if (format >= 1025) {
- format = FXDIB_Cmyka;
- } else if (format <= 32 || format == FXDIB_Argb) {
- format = FXDIB_Argb;
- } else {
- format = FXDIB_Rgba;
- }
- return format;
-}
-FX_BOOL CFX_ImageTransformer::Continue(IFX_Pause* pPause)
-{
- if (m_Status == 1) {
- if (m_Stretcher.Continue(pPause)) {
- return TRUE;
- }
- if (m_Storer.GetBitmap()) {
- m_Storer.Replace(m_Storer.GetBitmap()->SwapXY(m_pMatrix->c > 0, m_pMatrix->b < 0));
- }
- return FALSE;
- } else if (m_Status == 2) {
- return m_Stretcher.Continue(pPause);
- } else if (m_Status != 3) {
- return FALSE;
- }
- if (m_Stretcher.Continue(pPause)) {
- return TRUE;
- }
- int stretch_width = m_StretchClip.Width();
- int stretch_height = m_StretchClip.Height();
- if (m_Storer.GetBitmap() == NULL) {
- return FALSE;
- }
- FX_LPCBYTE stretch_buf = m_Storer.GetBitmap()->GetBuffer();
- FX_LPCBYTE stretch_buf_mask = NULL;
- if (m_Storer.GetBitmap()->m_pAlphaMask) {
- stretch_buf_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetBuffer();
- }
- int stretch_pitch = m_Storer.GetBitmap()->GetPitch();
- CFX_DIBitmap* pTransformed = FX_NEW CFX_DIBitmap;
- if (!pTransformed) {
- return FALSE;
- }
- FXDIB_Format transformF = _GetTransformedFormat(m_Stretcher.m_pSource);
- if (!pTransformed->Create(m_ResultWidth, m_ResultHeight, transformF)) {
- delete pTransformed;
- return FALSE;
- }
- pTransformed->Clear(0);
- if (pTransformed->m_pAlphaMask) {
- pTransformed->m_pAlphaMask->Clear(0);
- }
- CFX_AffineMatrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, (FX_FLOAT)(m_ResultLeft), (FX_FLOAT)(m_ResultTop));
- result2stretch.Concat(m_dest2stretch);
- result2stretch.TranslateI(-m_StretchClip.left, -m_StretchClip.top);
- if (stretch_buf_mask == NULL && pTransformed->m_pAlphaMask) {
- pTransformed->m_pAlphaMask->Clear(0xff000000);
- } else if (pTransformed->m_pAlphaMask) {
- int stretch_pitch_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetPitch();
- if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
- CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_BYTE* dest_pos_mask = (FX_BYTE*)pTransformed->m_pAlphaMask->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col_l, src_row_l, res_x, res_y;
- result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
- if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
- if (src_col_l == stretch_width) {
- src_col_l--;
- }
- if (src_row_l == stretch_height) {
- src_row_l--;
- }
- int src_col_r = src_col_l + 1;
- int src_row_r = src_row_l + 1;
- if (src_col_r == stretch_width) {
- src_col_r--;
- }
- if (src_row_r == stretch_height) {
- src_row_r--;
- }
- int row_offset_l = src_row_l * stretch_pitch_mask;
- int row_offset_r = src_row_r * stretch_pitch_mask;
- *dest_pos_mask = _bilinear_interpol(stretch_buf_mask, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0);
- }
- dest_pos_mask++;
- }
- }
- } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
- int pos_pixel[8];
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_BYTE* dest_pos_mask = (FX_BYTE*)pTransformed->m_pAlphaMask->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col_l, src_row_l, res_x, res_y;
- result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
- if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
- int u_w[4], v_w[4];
- if (src_col_l == stretch_width) {
- src_col_l--;
- }
- if (src_row_l == stretch_height) {
- src_row_l--;
- }
- _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
- *dest_pos_mask = _bicubic_interpol(stretch_buf_mask, stretch_pitch_mask, pos_pixel, u_w, v_w, res_x, res_y, 1, 0);
- }
- dest_pos_mask++;
- }
- }
- } else {
- CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_BYTE* dest_pos_mask = (FX_BYTE*)pTransformed->m_pAlphaMask->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col, src_row;
- result2stretch_fix.Transform(col, row, src_col, src_row);
- if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
- if (src_col == stretch_width) {
- src_col --;
- }
- if (src_row == stretch_height) {
- src_row --;
- }
- *dest_pos_mask = stretch_buf_mask[src_row * stretch_pitch_mask + src_col];
- }
- dest_pos_mask++;
- }
- }
- }
- }
- if (m_Storer.GetBitmap()->IsAlphaMask()) {
- if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
- CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_LPBYTE dest_scan = (FX_LPBYTE)pTransformed->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col_l, src_row_l, res_x, res_y;
- result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
- if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
- if (src_col_l == stretch_width) {
- src_col_l--;
- }
- if (src_row_l == stretch_height) {
- src_row_l--;
- }
- int src_col_r = src_col_l + 1;
- int src_row_r = src_row_l + 1;
- if (src_col_r == stretch_width) {
- src_col_r--;
- }
- if (src_row_r == stretch_height) {
- src_row_r--;
- }
- int row_offset_l = src_row_l * stretch_pitch;
- int row_offset_r = src_row_r * stretch_pitch;
- *dest_scan = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0);
- }
- dest_scan ++;
- }
- }
- } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
- int pos_pixel[8];
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_LPBYTE dest_scan = (FX_LPBYTE)pTransformed->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col_l, src_row_l, res_x, res_y;
- result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
- if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
- int u_w[4], v_w[4];
- if (src_col_l == stretch_width) {
- src_col_l--;
- }
- if (src_row_l == stretch_height) {
- src_row_l--;
- }
- _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
- *dest_scan = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, 1, 0);
- }
- dest_scan ++;
- }
- }
- } else {
- CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_LPBYTE dest_scan = (FX_LPBYTE)pTransformed->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col, src_row;
- result2stretch_fix.Transform(col, row, src_col, src_row);
- if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
- if (src_col == stretch_width) {
- src_col --;
- }
- if (src_row == stretch_height) {
- src_row --;
- }
- FX_LPCBYTE src_pixel = stretch_buf + stretch_pitch * src_row + src_col;
- *dest_scan = *src_pixel;
- }
- dest_scan ++;
- }
- }
- }
- } else {
- int Bpp = m_Storer.GetBitmap()->GetBPP() / 8;
- int destBpp = pTransformed->GetBPP() / 8;
- if (Bpp == 1) {
- FX_BOOL bHasAlpha = m_Storer.GetBitmap()->HasAlpha();
- FX_DWORD argb[256];
- FX_ARGB* pPal = m_Storer.GetBitmap()->GetPalette();
- if (pPal) {
- for (int i = 0; i < 256; i ++) {
- argb[i] = pPal[i];
- }
- } else {
- if (m_Storer.GetBitmap()->IsCmykImage())
- for (int i = 0; i < 256; i ++) {
- argb[i] = 255 - i;
- }
- else
- for (int i = 0; i < 256; i ++) {
- argb[i] = 0xff000000 | (i * 0x010101);
- }
- }
- if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
- CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col_l, src_row_l, res_x, res_y;
- result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
- if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
- if (src_col_l == stretch_width) {
- src_col_l--;
- }
- if (src_row_l == stretch_height) {
- src_row_l--;
- }
- int src_col_r = src_col_l + 1;
- int src_row_r = src_row_l + 1;
- if (src_col_r == stretch_width) {
- src_col_r--;
- }
- if (src_row_r == stretch_height) {
- src_row_r--;
- }
- int row_offset_l = src_row_l * stretch_pitch;
- int row_offset_r = src_row_r * stretch_pitch;
- FX_DWORD r_bgra_cmyk = argb[_bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0)];
- if (transformF == FXDIB_Rgba) {
- dest_pos[0] = (FX_BYTE)(r_bgra_cmyk >> 24);
- dest_pos[1] = (FX_BYTE)(r_bgra_cmyk >> 16);
- dest_pos[2] = (FX_BYTE)(r_bgra_cmyk >> 8);
- } else {
- *(FX_DWORD*)dest_pos = r_bgra_cmyk;
- }
- }
- dest_pos += destBpp;
- }
- }
- } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
- int pos_pixel[8];
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col_l, src_row_l, res_x, res_y;
- result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
- if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
- int u_w[4], v_w[4];
- if (src_col_l == stretch_width) {
- src_col_l--;
- }
- if (src_row_l == stretch_height) {
- src_row_l--;
- }
- _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
- FX_DWORD r_bgra_cmyk = argb[_bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, 1, 0)];
- if (transformF == FXDIB_Rgba) {
- dest_pos[0] = (FX_BYTE)(r_bgra_cmyk >> 24);
- dest_pos[1] = (FX_BYTE)(r_bgra_cmyk >> 16);
- dest_pos[2] = (FX_BYTE)(r_bgra_cmyk >> 8);
- } else {
- *(FX_DWORD*)dest_pos = r_bgra_cmyk;
- }
- }
- dest_pos += destBpp;
- }
- }
- } else {
- CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col, src_row;
- result2stretch_fix.Transform(col, row, src_col, src_row);
- if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
- if (src_col == stretch_width) {
- src_col --;
- }
- if (src_row == stretch_height) {
- src_row --;
- }
- FX_DWORD r_bgra_cmyk = argb[stretch_buf[src_row * stretch_pitch + src_col]];
- if (transformF == FXDIB_Rgba) {
- dest_pos[0] = (FX_BYTE)(r_bgra_cmyk >> 24);
- dest_pos[1] = (FX_BYTE)(r_bgra_cmyk >> 16);
- dest_pos[2] = (FX_BYTE)(r_bgra_cmyk >> 8);
- } else {
- *(FX_DWORD*)dest_pos = r_bgra_cmyk;
- }
- }
- dest_pos += destBpp;
- }
- }
- }
- } else {
- FX_BOOL bHasAlpha = m_Storer.GetBitmap()->HasAlpha();
- int destBpp = pTransformed->GetBPP() / 8;
- if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
- CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0;
- result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
- if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
- if (src_col_l == stretch_width) {
- src_col_l--;
- }
- if (src_row_l == stretch_height) {
- src_row_l--;
- }
- int src_col_r = src_col_l + 1;
- int src_row_r = src_row_l + 1;
- if (src_col_r == stretch_width) {
- src_col_r--;
- }
- if (src_row_r == stretch_height) {
- src_row_r--;
- }
- int row_offset_l = src_row_l * stretch_pitch;
- int row_offset_r = src_row_r * stretch_pitch;
- FX_BYTE r_pos_red_y_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 2);
- FX_BYTE r_pos_green_m_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 1);
- FX_BYTE r_pos_blue_c_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 0);
- if (bHasAlpha) {
- if (transformF != FXDIB_Argb) {
- if (transformF == FXDIB_Rgba) {
- dest_pos[0] = r_pos_blue_c_r;
- dest_pos[1] = r_pos_green_m_r;
- dest_pos[2] = r_pos_red_y_r;
- } else {
- r_pos_k_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 3);
- *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
- }
- } else {
- FX_BYTE r_pos_a_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 3);
- *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_a_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
- }
- } else {
- r_pos_k_r = 0xff;
- if (transformF == FXDIB_Cmyka) {
- r_pos_k_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 3);
- *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
- } else {
- *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_k_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
- }
- }
- }
- dest_pos += destBpp;
- }
- }
- } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
- CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
- int pos_pixel[8];
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0;
- result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
- if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
- int u_w[4], v_w[4];
- if (src_col_l == stretch_width) {
- src_col_l--;
- }
- if (src_row_l == stretch_height) {
- src_row_l--;
- }
- _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
- FX_BYTE r_pos_red_y_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 2);
- FX_BYTE r_pos_green_m_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 1);
- FX_BYTE r_pos_blue_c_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 0);
- if (bHasAlpha) {
- if (transformF != FXDIB_Argb) {
- if (transformF == FXDIB_Rgba) {
- dest_pos[0] = r_pos_blue_c_r;
- dest_pos[1] = r_pos_green_m_r;
- dest_pos[2] = r_pos_red_y_r;
- } else {
- r_pos_k_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 3);
- *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
- }
- } else {
- FX_BYTE r_pos_a_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 3);
- *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_a_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
- }
- } else {
- r_pos_k_r = 0xff;
- if (transformF == FXDIB_Cmyka) {
- r_pos_k_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 3);
- *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
- } else {
- *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_k_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
- }
- }
- }
- dest_pos += destBpp;
- }
- }
- } else {
- CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
- for (int row = 0; row < m_ResultHeight; row ++) {
- FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
- for (int col = 0; col < m_ResultWidth; col ++) {
- int src_col, src_row;
- result2stretch_fix.Transform(col, row, src_col, src_row);
- if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
- if (src_col == stretch_width) {
- src_col --;
- }
- if (src_row == stretch_height) {
- src_row --;
- }
- FX_LPCBYTE src_pos = stretch_buf + src_row * stretch_pitch + src_col * Bpp;
- if (bHasAlpha) {
- if (transformF != FXDIB_Argb) {
- if (transformF == FXDIB_Rgba) {
- dest_pos[0] = src_pos[0];
- dest_pos[1] = src_pos[1];
- dest_pos[2] = src_pos[2];
- } else {
- *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(src_pos[0], src_pos[1], src_pos[2], src_pos[3]));
- }
- } else {
- *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(src_pos[3], src_pos[2], src_pos[1], src_pos[0]));
- }
- } else {
- if (transformF == FXDIB_Cmyka) {
- *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(src_pos[0], src_pos[1], src_pos[2], src_pos[3]));
- } else {
- *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(0xff, src_pos[2], src_pos[1], src_pos[0]));
- }
- }
- }
- dest_pos += destBpp;
- }
- }
- }
- }
- }
- m_Storer.Replace(pTransformed);
- return FALSE;
-}
+// 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 "../../../include/fxge/fx_dib.h"
+#include "dib_int.h"
+int SDP_Table[513] = {
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 255, 255, 255, 255, 255, 255, 254, 254, 254, 254,
+ 253, 253, 253, 252, 252, 252, 251, 251, 251, 250, 250, 249, 249, 249, 248, 248, 247, 247, 246,
+ 246, 245, 244, 244, 243, 243, 242, 242, 241, 240, 240, 239, 238, 238, 237, 236, 236, 235, 234,
+ 233, 233, 232, 231, 230, 230, 229, 228, 227, 226, 226, 225, 224, 223, 222, 221, 220, 219, 218,
+ 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, 207, 206, 205, 204, 203, 202, 201, 200,
+ 199, 198, 196, 195, 194, 193, 192, 191, 190, 189, 188, 186, 185, 184, 183, 182, 181, 179, 178,
+ 177, 176, 175, 173, 172, 171, 170, 169, 167, 166, 165, 164, 162, 161, 160, 159, 157, 156, 155,
+ 154, 152, 151, 150, 149, 147, 146, 145, 143, 142, 141, 140, 138, 137, 136, 134, 133, 132, 130,
+ 129, 128, 126, 125, 124, 122, 121, 120, 119, 117, 116, 115, 113, 112, 111, 109, 108, 107, 105,
+ 104, 103, 101, 100, 99, 97, 96, 95, 93, 92, 91, 89, 88, 87, 85, 84, 83, 81, 80, 79, 77, 76, 75,
+ 73, 72, 71, 69, 68, 67, 66, 64, 63, 62, 60, 59, 58, 57, 55, 54, 53, 52, 50, 49, 48, 47, 45, 44,
+ 43, 42, 40, 39, 38, 37, 36, 34, 33, 32, 31, 30, 28, 27, 26, 25, 24, 23, 21, 20, 19, 18, 17, 16,
+ 15, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, -1, -2, -3, -4, -5, -6, -7, -7, -8, -9, -10,
+ -11, -12, -12, -13, -14, -15, -15, -16, -17, -17, -18, -19, -19, -20, -21, -21, -22, -22, -23, -24,
+ -24, -25, -25, -26, -26, -27, -27, -27, -28, -28, -29, -29, -30, -30, -30, -31, -31, -31, -32, -32,
+ -32, -33, -33, -33, -33, -34, -34, -34, -34, -35, -35, -35, -35, -35, -36, -36, -36, -36, -36, -36,
+ -36, -36, -36, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, -37,
+ -37, -37, -37, -37, -36, -36, -36, -36, -36, -36, -36, -36, -36, -35, -35, -35, -35, -35, -35, -34,
+ -34, -34, -34, -34, -33, -33, -33, -33, -33, -32, -32, -32, -32, -31, -31, -31, -31, -30, -30, -30,
+ -30, -29, -29, -29, -29, -28, -28, -28, -27, -27, -27, -27, -26, -26, -26, -25, -25, -25, -24, -24,
+ -24, -23, -23, -23, -22, -22, -22, -22, -21, -21, -21, -20, -20, -20, -19, -19, -19, -18, -18, -18,
+ -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -12, -12, -12, -11, -11,
+ -11, -10, -10, -10, -9, -9, -9, -9, -8, -8, -8, -7, -7, -7, -7, -6, -6, -6, -6, -5, -5, -5, -5, -4,
+ -4, -4, -4, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+class CFX_BilinearMatrix : public CPDF_FixedMatrix
+{
+public:
+ CFX_BilinearMatrix(const CFX_AffineMatrix& src, int bits): CPDF_FixedMatrix(src, bits)
+ {}
+ inline void Transform(int x, int y, int& x1, int& y1, int&res_x, int&res_y)
+ {
+ x1 = a * x + c * y + e + base / 2;
+ y1 = b * x + d * y + f + base / 2;
+ res_x = x1 % base;
+ res_y = y1 % base;
+ if (res_x < 0 && res_x > -base) {
+ res_x = base + res_x;
+ }
+ if (res_y < 0 && res_x > -base) {
+ res_y = base + res_y;
+ }
+ x1 /= base;
+ y1 /= base;
+ }
+};
+CFX_DIBitmap* CFX_DIBSource::SwapXY(FX_BOOL bXFlip, FX_BOOL bYFlip, const FX_RECT* pDestClip) const
+{
+ FX_RECT dest_clip(0, 0, m_Height, m_Width);
+ if (pDestClip) {
+ dest_clip.Intersect(*pDestClip);
+ }
+ if (dest_clip.IsEmpty()) {
+ return NULL;
+ }
+ CFX_DIBitmap* pTransBitmap = FX_NEW CFX_DIBitmap;
+ if (!pTransBitmap) {
+ return NULL;
+ }
+ int result_height = dest_clip.Height(), result_width = dest_clip.Width();
+ if (!pTransBitmap->Create(result_width, result_height, GetFormat())) {
+ delete pTransBitmap;
+ return NULL;
+ }
+ pTransBitmap->CopyPalette(m_pPalette);
+ int src_pitch = m_Pitch;
+ int dest_pitch = pTransBitmap->GetPitch();
+ FX_LPBYTE dest_buf = pTransBitmap->GetBuffer();
+ int row_start = bXFlip ? m_Height - dest_clip.right : dest_clip.left;
+ int row_end = bXFlip ? m_Height - dest_clip.left : dest_clip.right;
+ int col_start = bYFlip ? m_Width - dest_clip.bottom : dest_clip.top;
+ int col_end = bYFlip ? m_Width - dest_clip.top : dest_clip.bottom;
+ if (GetBPP() == 1) {
+ FXSYS_memset8(dest_buf, 0xff, dest_pitch * result_height);
+ for (int row = row_start; row < row_end; row ++) {
+ FX_LPCBYTE src_scan = GetScanline(row);
+ int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left;
+ FX_LPBYTE dest_scan = dest_buf;
+ if (bYFlip) {
+ dest_scan += (result_height - 1) * dest_pitch;
+ }
+ int dest_step = bYFlip ? -dest_pitch : dest_pitch;
+ for (int col = col_start; col < col_end; col ++) {
+ if (!(src_scan[col / 8] & (1 << (7 - col % 8)))) {
+ dest_scan[dest_col / 8] &= ~(1 << (7 - dest_col % 8));
+ }
+ dest_scan += dest_step;
+ }
+ }
+ } else {
+ int nBytes = GetBPP() / 8;
+ int dest_step = bYFlip ? -dest_pitch : dest_pitch;
+ if (nBytes == 3) {
+ dest_step -= 2;
+ }
+ for (int row = row_start; row < row_end; row ++) {
+ int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left;
+ FX_LPBYTE dest_scan = dest_buf + dest_col * nBytes;
+ if (bYFlip) {
+ dest_scan += (result_height - 1) * dest_pitch;
+ }
+ if (nBytes == 4) {
+ FX_DWORD* src_scan = (FX_DWORD*)GetScanline(row) + col_start;
+ for (int col = col_start; col < col_end; col ++) {
+ *(FX_DWORD*)dest_scan = *src_scan++;
+ dest_scan += dest_step;
+ }
+ } else {
+ FX_LPCBYTE src_scan = GetScanline(row) + col_start * nBytes;
+ if (nBytes == 1)
+ for (int col = col_start; col < col_end; col ++) {
+ *dest_scan = *src_scan++;
+ dest_scan += dest_step;
+ }
+ else
+ for (int col = col_start; col < col_end; col ++) {
+ *dest_scan++ = *src_scan++;
+ *dest_scan++ = *src_scan++;
+ *dest_scan = *src_scan++;
+ dest_scan += dest_step;
+ }
+ }
+ }
+ }
+ if (m_pAlphaMask) {
+ src_pitch = m_pAlphaMask->m_Pitch;
+ dest_pitch = pTransBitmap->m_pAlphaMask->GetPitch();
+ dest_buf = pTransBitmap->m_pAlphaMask->GetBuffer();
+ int dest_step = bYFlip ? -dest_pitch : dest_pitch;
+ for (int row = row_start; row < row_end; row ++) {
+ int dest_col = (bXFlip ? dest_clip.right - (row - row_start) - 1 : row) - dest_clip.left;
+ FX_LPBYTE dest_scan = dest_buf + dest_col;
+ if (bYFlip) {
+ dest_scan += (result_height - 1) * dest_pitch;
+ }
+ FX_LPCBYTE src_scan = m_pAlphaMask->GetScanline(row) + col_start;
+ for (int col = col_start; col < col_end; col ++) {
+ *dest_scan = *src_scan++;
+ dest_scan += dest_step;
+ }
+ }
+ }
+ return pTransBitmap;
+}
+#define FIX16_005 0.05f
+FX_RECT _FXDIB_SwapClipBox(FX_RECT& clip, int width, int height, FX_BOOL bFlipX, FX_BOOL bFlipY)
+{
+ FX_RECT rect;
+ if (bFlipY) {
+ rect.left = height - clip.top;
+ rect.right = height - clip.bottom;
+ } else {
+ rect.left = clip.top;
+ rect.right = clip.bottom;
+ }
+ if (bFlipX) {
+ rect.top = width - clip.left;
+ rect.bottom = width - clip.right;
+ } else {
+ rect.top = clip.left;
+ rect.bottom = clip.right;
+ }
+ rect.Normalize();
+ return rect;
+}
+CFX_DIBitmap* CFX_DIBSource::TransformTo(const CFX_AffineMatrix* pDestMatrix, int& result_left, int& result_top,
+ FX_DWORD flags, const FX_RECT* pDestClip) const
+{
+ CFX_ImageTransformer transformer;
+ transformer.Start(this, pDestMatrix, flags, pDestClip);
+ transformer.Continue(NULL);
+ result_left = transformer.m_ResultLeft;
+ result_top = transformer.m_ResultTop;
+ CFX_DIBitmap* pTransformed = transformer.m_Storer.Detach();
+ return pTransformed;
+}
+CFX_DIBitmap* CFX_DIBSource::StretchTo(int dest_width, int dest_height, FX_DWORD flags, const FX_RECT* pClip) const
+{
+ FX_RECT clip_rect(0, 0, FXSYS_abs(dest_width), FXSYS_abs(dest_height));
+ if (pClip) {
+ clip_rect.Intersect(*pClip);
+ }
+ if (clip_rect.IsEmpty()) {
+ return NULL;
+ }
+ if (dest_width == m_Width && dest_height == m_Height) {
+ return Clone(&clip_rect);
+ }
+ CFX_ImageStretcher stretcher;
+ CFX_BitmapStorer storer;
+ if (stretcher.Start(&storer, this, dest_width, dest_height, clip_rect, flags)) {
+ stretcher.Continue(NULL);
+ }
+ return storer.Detach();
+}
+CFX_ImageTransformer::CFX_ImageTransformer()
+{
+ m_Status = 0;
+ m_pMatrix = NULL;
+}
+CFX_ImageTransformer::~CFX_ImageTransformer()
+{
+}
+FX_BOOL CFX_ImageTransformer::Start(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix, int flags, const FX_RECT* pDestClip)
+{
+ m_pMatrix = (CFX_AffineMatrix*)pDestMatrix;
+ CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect();
+ FX_RECT result_rect = unit_rect.GetClosestRect();
+ FX_RECT result_clip = result_rect;
+ if (pDestClip) {
+ result_clip.Intersect(*pDestClip);
+ }
+ if (result_clip.IsEmpty()) {
+ return FALSE;
+ }
+ m_ResultLeft = result_clip.left;
+ m_ResultTop = result_clip.top;
+ m_ResultWidth = result_clip.Width();
+ m_ResultHeight = result_clip.Height();
+ m_Flags = flags;
+ if (FXSYS_fabs(pDestMatrix->a) < FXSYS_fabs(pDestMatrix->b) / 20 &&
+ FXSYS_fabs(pDestMatrix->d) < FXSYS_fabs(pDestMatrix->c) / 20 &&
+ FXSYS_fabs(pDestMatrix->a) < 0.5f && FXSYS_fabs(pDestMatrix->d) < 0.5f) {
+ int dest_width = result_rect.Width();
+ int dest_height = result_rect.Height();
+ result_clip.Offset(-result_rect.left, -result_rect.top);
+ result_clip = _FXDIB_SwapClipBox(result_clip, dest_width, dest_height, pDestMatrix->c > 0, pDestMatrix->b < 0);
+ m_Stretcher.Start(&m_Storer, pSrc, dest_height, dest_width, result_clip, flags);
+ m_Status = 1;
+ return TRUE;
+ }
+ if (FXSYS_fabs(pDestMatrix->b) < FIX16_005 && FXSYS_fabs(pDestMatrix->c) < FIX16_005) {
+ int dest_width = pDestMatrix->a > 0 ? (int)FXSYS_ceil(pDestMatrix->a) : (int)FXSYS_floor(pDestMatrix->a);
+ int dest_height = pDestMatrix->d > 0 ? (int) - FXSYS_ceil(pDestMatrix->d) : (int) - FXSYS_floor(pDestMatrix->d);
+ result_clip.Offset(-result_rect.left, -result_rect.top);
+ m_Stretcher.Start(&m_Storer, pSrc, dest_width, dest_height, result_clip, flags);
+ m_Status = 2;
+ return TRUE;
+ }
+ int stretch_width = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->a, pDestMatrix->b));
+ int stretch_height = (int)FXSYS_ceil(FXSYS_sqrt2(pDestMatrix->c, pDestMatrix->d));
+ CFX_AffineMatrix stretch2dest(1.0f, 0.0f, 0.0f, -1.0f, 0.0f, (FX_FLOAT)(stretch_height));
+ stretch2dest.Concat(pDestMatrix->a / stretch_width, pDestMatrix->b / stretch_width,
+ pDestMatrix->c / stretch_height, pDestMatrix->d / stretch_height, pDestMatrix->e, pDestMatrix->f);
+ m_dest2stretch.SetReverse(stretch2dest);
+ CFX_FloatRect clip_rect_f(result_clip);
+ clip_rect_f.Transform(&m_dest2stretch);
+ m_StretchClip = clip_rect_f.GetOutterRect();
+ m_StretchClip.Intersect(0, 0, stretch_width, stretch_height);
+ m_Stretcher.Start(&m_Storer, pSrc, stretch_width, stretch_height, m_StretchClip, flags);
+ m_Status = 3;
+ return TRUE;
+}
+FX_BYTE _bilinear_interpol(FX_LPCBYTE buf, int row_offset_l, int row_offset_r,
+ int src_col_l, int src_col_r, int res_x, int res_y,
+ int bpp, int c_offset)
+{
+ int i_resx = 255 - res_x;
+ int col_bpp_l = src_col_l * bpp;
+ int col_bpp_r = src_col_r * bpp;
+ FX_LPCBYTE buf_u = buf + row_offset_l + c_offset;
+ FX_LPCBYTE buf_d = buf + row_offset_r + c_offset;
+ FX_LPCBYTE src_pos0 = buf_u + col_bpp_l;
+ FX_LPCBYTE src_pos1 = buf_u + col_bpp_r;
+ FX_LPCBYTE src_pos2 = buf_d + col_bpp_l;
+ FX_LPCBYTE src_pos3 = buf_d + col_bpp_r;
+ FX_BYTE r_pos_0 = (*src_pos0 * i_resx + *src_pos1 * res_x) >> 8;
+ FX_BYTE r_pos_1 = (*src_pos2 * i_resx + *src_pos3 * res_x) >> 8;
+ return (r_pos_0 * (255 - res_y) + r_pos_1 * res_y) >> 8;
+}
+FX_BYTE _bicubic_interpol(FX_LPCBYTE buf, int pitch, int pos_pixel[], int u_w[], int v_w[], int res_x, int res_y,
+ int bpp, int c_offset)
+{
+ int s_result = 0;
+ for (int i = 0; i < 4; i ++) {
+ int a_result = 0;
+ for (int j = 0; j < 4; j ++) {
+ a_result += u_w[j] * (*(FX_BYTE*)(buf + pos_pixel[i + 4] * pitch + pos_pixel[j] * bpp + c_offset));
+ }
+ s_result += a_result * v_w[i];
+ }
+ s_result >>= 16;
+ return (FX_BYTE)(s_result < 0 ? 0 : s_result > 255 ? 255 : s_result);
+}
+void _bicubic_get_pos_weight(int pos_pixel[], int u_w[], int v_w[], int src_col_l, int src_row_l,
+ int res_x, int res_y, int stretch_width, int stretch_height)
+{
+ pos_pixel[0] = src_col_l - 1;
+ pos_pixel[1] = src_col_l;
+ pos_pixel[2] = src_col_l + 1;
+ pos_pixel[3] = src_col_l + 2;
+ pos_pixel[4] = src_row_l - 1;
+ pos_pixel[5] = src_row_l;
+ pos_pixel[6] = src_row_l + 1;
+ pos_pixel[7] = src_row_l + 2;
+ for (int i = 0 ; i < 4; i ++) {
+ if (pos_pixel[i] < 0) {
+ pos_pixel[i] = 0;
+ }
+ if (pos_pixel[i] >= stretch_width) {
+ pos_pixel[i] = stretch_width - 1;
+ }
+ if (pos_pixel[i + 4] < 0) {
+ pos_pixel[i + 4] = 0;
+ }
+ if (pos_pixel[i + 4] >= stretch_height) {
+ pos_pixel[i + 4] = stretch_height - 1;
+ }
+ }
+ u_w[0] = SDP_Table[256 + res_x];
+ u_w[1] = SDP_Table[res_x];
+ u_w[2] = SDP_Table[256 - res_x];
+ u_w[3] = SDP_Table[512 - res_x];
+ v_w[0] = SDP_Table[256 + res_y];
+ v_w[1] = SDP_Table[res_y];
+ v_w[2] = SDP_Table[256 - res_y];
+ v_w[3] = SDP_Table[512 - res_y];
+}
+FXDIB_Format _GetTransformedFormat(const CFX_DIBSource* pDrc)
+{
+ FXDIB_Format format = pDrc->GetFormat();
+ if (pDrc->IsAlphaMask()) {
+ format = FXDIB_8bppMask;
+ } else if (format >= 1025) {
+ format = FXDIB_Cmyka;
+ } else if (format <= 32 || format == FXDIB_Argb) {
+ format = FXDIB_Argb;
+ } else {
+ format = FXDIB_Rgba;
+ }
+ return format;
+}
+FX_BOOL CFX_ImageTransformer::Continue(IFX_Pause* pPause)
+{
+ if (m_Status == 1) {
+ if (m_Stretcher.Continue(pPause)) {
+ return TRUE;
+ }
+ if (m_Storer.GetBitmap()) {
+ m_Storer.Replace(m_Storer.GetBitmap()->SwapXY(m_pMatrix->c > 0, m_pMatrix->b < 0));
+ }
+ return FALSE;
+ } else if (m_Status == 2) {
+ return m_Stretcher.Continue(pPause);
+ } else if (m_Status != 3) {
+ return FALSE;
+ }
+ if (m_Stretcher.Continue(pPause)) {
+ return TRUE;
+ }
+ int stretch_width = m_StretchClip.Width();
+ int stretch_height = m_StretchClip.Height();
+ if (m_Storer.GetBitmap() == NULL) {
+ return FALSE;
+ }
+ FX_LPCBYTE stretch_buf = m_Storer.GetBitmap()->GetBuffer();
+ FX_LPCBYTE stretch_buf_mask = NULL;
+ if (m_Storer.GetBitmap()->m_pAlphaMask) {
+ stretch_buf_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetBuffer();
+ }
+ int stretch_pitch = m_Storer.GetBitmap()->GetPitch();
+ CFX_DIBitmap* pTransformed = FX_NEW CFX_DIBitmap;
+ if (!pTransformed) {
+ return FALSE;
+ }
+ FXDIB_Format transformF = _GetTransformedFormat(m_Stretcher.m_pSource);
+ if (!pTransformed->Create(m_ResultWidth, m_ResultHeight, transformF)) {
+ delete pTransformed;
+ return FALSE;
+ }
+ pTransformed->Clear(0);
+ if (pTransformed->m_pAlphaMask) {
+ pTransformed->m_pAlphaMask->Clear(0);
+ }
+ CFX_AffineMatrix result2stretch(1.0f, 0.0f, 0.0f, 1.0f, (FX_FLOAT)(m_ResultLeft), (FX_FLOAT)(m_ResultTop));
+ result2stretch.Concat(m_dest2stretch);
+ result2stretch.TranslateI(-m_StretchClip.left, -m_StretchClip.top);
+ if (stretch_buf_mask == NULL && pTransformed->m_pAlphaMask) {
+ pTransformed->m_pAlphaMask->Clear(0xff000000);
+ } else if (pTransformed->m_pAlphaMask) {
+ int stretch_pitch_mask = m_Storer.GetBitmap()->m_pAlphaMask->GetPitch();
+ if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_BYTE* dest_pos_mask = (FX_BYTE*)pTransformed->m_pAlphaMask->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ int src_col_r = src_col_l + 1;
+ int src_row_r = src_row_l + 1;
+ if (src_col_r == stretch_width) {
+ src_col_r--;
+ }
+ if (src_row_r == stretch_height) {
+ src_row_r--;
+ }
+ int row_offset_l = src_row_l * stretch_pitch_mask;
+ int row_offset_r = src_row_r * stretch_pitch_mask;
+ *dest_pos_mask = _bilinear_interpol(stretch_buf_mask, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0);
+ }
+ dest_pos_mask++;
+ }
+ }
+ } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ int pos_pixel[8];
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_BYTE* dest_pos_mask = (FX_BYTE*)pTransformed->m_pAlphaMask->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
+ int u_w[4], v_w[4];
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
+ *dest_pos_mask = _bicubic_interpol(stretch_buf_mask, stretch_pitch_mask, pos_pixel, u_w, v_w, res_x, res_y, 1, 0);
+ }
+ dest_pos_mask++;
+ }
+ }
+ } else {
+ CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_BYTE* dest_pos_mask = (FX_BYTE*)pTransformed->m_pAlphaMask->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col, src_row;
+ result2stretch_fix.Transform(col, row, src_col, src_row);
+ if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
+ if (src_col == stretch_width) {
+ src_col --;
+ }
+ if (src_row == stretch_height) {
+ src_row --;
+ }
+ *dest_pos_mask = stretch_buf_mask[src_row * stretch_pitch_mask + src_col];
+ }
+ dest_pos_mask++;
+ }
+ }
+ }
+ }
+ if (m_Storer.GetBitmap()->IsAlphaMask()) {
+ if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_LPBYTE dest_scan = (FX_LPBYTE)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ int src_col_r = src_col_l + 1;
+ int src_row_r = src_row_l + 1;
+ if (src_col_r == stretch_width) {
+ src_col_r--;
+ }
+ if (src_row_r == stretch_height) {
+ src_row_r--;
+ }
+ int row_offset_l = src_row_l * stretch_pitch;
+ int row_offset_r = src_row_r * stretch_pitch;
+ *dest_scan = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0);
+ }
+ dest_scan ++;
+ }
+ }
+ } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ int pos_pixel[8];
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_LPBYTE dest_scan = (FX_LPBYTE)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
+ int u_w[4], v_w[4];
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
+ *dest_scan = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, 1, 0);
+ }
+ dest_scan ++;
+ }
+ }
+ } else {
+ CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_LPBYTE dest_scan = (FX_LPBYTE)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col, src_row;
+ result2stretch_fix.Transform(col, row, src_col, src_row);
+ if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
+ if (src_col == stretch_width) {
+ src_col --;
+ }
+ if (src_row == stretch_height) {
+ src_row --;
+ }
+ FX_LPCBYTE src_pixel = stretch_buf + stretch_pitch * src_row + src_col;
+ *dest_scan = *src_pixel;
+ }
+ dest_scan ++;
+ }
+ }
+ }
+ } else {
+ int Bpp = m_Storer.GetBitmap()->GetBPP() / 8;
+ int destBpp = pTransformed->GetBPP() / 8;
+ if (Bpp == 1) {
+ FX_BOOL bHasAlpha = m_Storer.GetBitmap()->HasAlpha();
+ FX_DWORD argb[256];
+ FX_ARGB* pPal = m_Storer.GetBitmap()->GetPalette();
+ if (pPal) {
+ for (int i = 0; i < 256; i ++) {
+ argb[i] = pPal[i];
+ }
+ } else {
+ if (m_Storer.GetBitmap()->IsCmykImage())
+ for (int i = 0; i < 256; i ++) {
+ argb[i] = 255 - i;
+ }
+ else
+ for (int i = 0; i < 256; i ++) {
+ argb[i] = 0xff000000 | (i * 0x010101);
+ }
+ }
+ if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ int src_col_r = src_col_l + 1;
+ int src_row_r = src_row_l + 1;
+ if (src_col_r == stretch_width) {
+ src_col_r--;
+ }
+ if (src_row_r == stretch_height) {
+ src_row_r--;
+ }
+ int row_offset_l = src_row_l * stretch_pitch;
+ int row_offset_r = src_row_r * stretch_pitch;
+ FX_DWORD r_bgra_cmyk = argb[_bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, 1, 0)];
+ if (transformF == FXDIB_Rgba) {
+ dest_pos[0] = (FX_BYTE)(r_bgra_cmyk >> 24);
+ dest_pos[1] = (FX_BYTE)(r_bgra_cmyk >> 16);
+ dest_pos[2] = (FX_BYTE)(r_bgra_cmyk >> 8);
+ } else {
+ *(FX_DWORD*)dest_pos = r_bgra_cmyk;
+ }
+ }
+ dest_pos += destBpp;
+ }
+ }
+ } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ int pos_pixel[8];
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col_l, src_row_l, res_x, res_y;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
+ int u_w[4], v_w[4];
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
+ FX_DWORD r_bgra_cmyk = argb[_bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, 1, 0)];
+ if (transformF == FXDIB_Rgba) {
+ dest_pos[0] = (FX_BYTE)(r_bgra_cmyk >> 24);
+ dest_pos[1] = (FX_BYTE)(r_bgra_cmyk >> 16);
+ dest_pos[2] = (FX_BYTE)(r_bgra_cmyk >> 8);
+ } else {
+ *(FX_DWORD*)dest_pos = r_bgra_cmyk;
+ }
+ }
+ dest_pos += destBpp;
+ }
+ }
+ } else {
+ CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col, src_row;
+ result2stretch_fix.Transform(col, row, src_col, src_row);
+ if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
+ if (src_col == stretch_width) {
+ src_col --;
+ }
+ if (src_row == stretch_height) {
+ src_row --;
+ }
+ FX_DWORD r_bgra_cmyk = argb[stretch_buf[src_row * stretch_pitch + src_col]];
+ if (transformF == FXDIB_Rgba) {
+ dest_pos[0] = (FX_BYTE)(r_bgra_cmyk >> 24);
+ dest_pos[1] = (FX_BYTE)(r_bgra_cmyk >> 16);
+ dest_pos[2] = (FX_BYTE)(r_bgra_cmyk >> 8);
+ } else {
+ *(FX_DWORD*)dest_pos = r_bgra_cmyk;
+ }
+ }
+ dest_pos += destBpp;
+ }
+ }
+ }
+ } else {
+ FX_BOOL bHasAlpha = m_Storer.GetBitmap()->HasAlpha();
+ int destBpp = pTransformed->GetBPP() / 8;
+ if (!(m_Flags & FXDIB_DOWNSAMPLE) && !(m_Flags & FXDIB_BICUBIC_INTERPOL)) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ int src_col_r = src_col_l + 1;
+ int src_row_r = src_row_l + 1;
+ if (src_col_r == stretch_width) {
+ src_col_r--;
+ }
+ if (src_row_r == stretch_height) {
+ src_row_r--;
+ }
+ int row_offset_l = src_row_l * stretch_pitch;
+ int row_offset_r = src_row_r * stretch_pitch;
+ FX_BYTE r_pos_red_y_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 2);
+ FX_BYTE r_pos_green_m_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 1);
+ FX_BYTE r_pos_blue_c_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 0);
+ if (bHasAlpha) {
+ if (transformF != FXDIB_Argb) {
+ if (transformF == FXDIB_Rgba) {
+ dest_pos[0] = r_pos_blue_c_r;
+ dest_pos[1] = r_pos_green_m_r;
+ dest_pos[2] = r_pos_red_y_r;
+ } else {
+ r_pos_k_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 3);
+ *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
+ }
+ } else {
+ FX_BYTE r_pos_a_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 3);
+ *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_a_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
+ }
+ } else {
+ r_pos_k_r = 0xff;
+ if (transformF == FXDIB_Cmyka) {
+ r_pos_k_r = _bilinear_interpol(stretch_buf, row_offset_l, row_offset_r, src_col_l, src_col_r, res_x, res_y, Bpp, 3);
+ *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
+ } else {
+ *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_k_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
+ }
+ }
+ }
+ dest_pos += destBpp;
+ }
+ }
+ } else if (m_Flags & FXDIB_BICUBIC_INTERPOL) {
+ CFX_BilinearMatrix result2stretch_fix(result2stretch, 8);
+ int pos_pixel[8];
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col_l, src_row_l, res_x, res_y, r_pos_k_r = 0;
+ result2stretch_fix.Transform(col, row, src_col_l, src_row_l, res_x, res_y);
+ if (src_col_l >= 0 && src_col_l <= stretch_width && src_row_l >= 0 && src_row_l <= stretch_height) {
+ int u_w[4], v_w[4];
+ if (src_col_l == stretch_width) {
+ src_col_l--;
+ }
+ if (src_row_l == stretch_height) {
+ src_row_l--;
+ }
+ _bicubic_get_pos_weight(pos_pixel, u_w, v_w, src_col_l, src_row_l, res_x, res_y, stretch_width, stretch_height);
+ FX_BYTE r_pos_red_y_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 2);
+ FX_BYTE r_pos_green_m_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 1);
+ FX_BYTE r_pos_blue_c_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 0);
+ if (bHasAlpha) {
+ if (transformF != FXDIB_Argb) {
+ if (transformF == FXDIB_Rgba) {
+ dest_pos[0] = r_pos_blue_c_r;
+ dest_pos[1] = r_pos_green_m_r;
+ dest_pos[2] = r_pos_red_y_r;
+ } else {
+ r_pos_k_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 3);
+ *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
+ }
+ } else {
+ FX_BYTE r_pos_a_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 3);
+ *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_a_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
+ }
+ } else {
+ r_pos_k_r = 0xff;
+ if (transformF == FXDIB_Cmyka) {
+ r_pos_k_r = _bicubic_interpol(stretch_buf, stretch_pitch, pos_pixel, u_w, v_w, res_x, res_y, Bpp, 3);
+ *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(r_pos_blue_c_r, r_pos_green_m_r, r_pos_red_y_r, r_pos_k_r));
+ } else {
+ *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(r_pos_k_r, r_pos_red_y_r, r_pos_green_m_r, r_pos_blue_c_r));
+ }
+ }
+ }
+ dest_pos += destBpp;
+ }
+ }
+ } else {
+ CPDF_FixedMatrix result2stretch_fix(result2stretch, 8);
+ for (int row = 0; row < m_ResultHeight; row ++) {
+ FX_BYTE* dest_pos = (FX_BYTE*)pTransformed->GetScanline(row);
+ for (int col = 0; col < m_ResultWidth; col ++) {
+ int src_col, src_row;
+ result2stretch_fix.Transform(col, row, src_col, src_row);
+ if (src_col >= 0 && src_col <= stretch_width && src_row >= 0 && src_row <= stretch_height) {
+ if (src_col == stretch_width) {
+ src_col --;
+ }
+ if (src_row == stretch_height) {
+ src_row --;
+ }
+ FX_LPCBYTE src_pos = stretch_buf + src_row * stretch_pitch + src_col * Bpp;
+ if (bHasAlpha) {
+ if (transformF != FXDIB_Argb) {
+ if (transformF == FXDIB_Rgba) {
+ dest_pos[0] = src_pos[0];
+ dest_pos[1] = src_pos[1];
+ dest_pos[2] = src_pos[2];
+ } else {
+ *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(src_pos[0], src_pos[1], src_pos[2], src_pos[3]));
+ }
+ } else {
+ *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(src_pos[3], src_pos[2], src_pos[1], src_pos[0]));
+ }
+ } else {
+ if (transformF == FXDIB_Cmyka) {
+ *(FX_DWORD*)dest_pos = FXCMYK_TODIB(CmykEncode(src_pos[0], src_pos[1], src_pos[2], src_pos[3]));
+ } else {
+ *(FX_DWORD*)dest_pos = FXARGB_TODIB(FXARGB_MAKE(0xff, src_pos[2], src_pos[1], src_pos[0]));
+ }
+ }
+ }
+ dest_pos += destBpp;
+ }
+ }
+ }
+ }
+ }
+ m_Storer.Replace(pTransformed);
+ return FALSE;
+}
diff --git a/core/src/fxge/ge/fx_ge.cpp b/core/src/fxge/ge/fx_ge.cpp
index df200d5b48..d044d721e6 100644
--- a/core/src/fxge/ge/fx_ge.cpp
+++ b/core/src/fxge/ge/fx_ge.cpp
@@ -1,79 +1,79 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#include "text_int.h"
-static CFX_GEModule* g_pGEModule = NULL;
-CFX_GEModule::CFX_GEModule()
-{
- m_pFontCache = NULL;
- m_pFontMgr = NULL;
- m_FTLibrary = NULL;
- m_pCodecModule = NULL;
- m_pPlatformData = NULL;
-}
-CFX_GEModule::~CFX_GEModule()
-{
- if (m_pFontCache) {
- delete m_pFontCache;
- }
- m_pFontCache = NULL;
- if (m_pFontMgr) {
- delete m_pFontMgr;
- }
- m_pFontMgr = NULL;
- DestroyPlatform();
-}
-CFX_GEModule* CFX_GEModule::Get()
-{
- return g_pGEModule;
-}
-void CFX_GEModule::Create()
-{
- g_pGEModule = FX_NEW CFX_GEModule;
- if (!g_pGEModule) {
- return;
- }
- g_pGEModule->m_pFontMgr = FX_NEW CFX_FontMgr;
- g_pGEModule->InitPlatform();
- g_pGEModule->SetTextGamma(2.2f);
-}
-void CFX_GEModule::Use(CFX_GEModule* pModule)
-{
- g_pGEModule = pModule;
-}
-void CFX_GEModule::Destroy()
-{
- if (g_pGEModule) {
- delete g_pGEModule;
- }
- g_pGEModule = NULL;
-}
-CFX_FontCache* CFX_GEModule::GetFontCache()
-{
- if (m_pFontCache == NULL) {
- m_pFontCache = FX_NEW CFX_FontCache();
- }
- return m_pFontCache;
-}
-void CFX_GEModule::SetTextGamma(FX_FLOAT gammaValue)
-{
- gammaValue /= 2.2f;
- int i = 0;
- while (i < 256) {
- m_GammaValue[i] = (FX_BYTE)(FXSYS_pow((FX_FLOAT)i / 255, gammaValue) * 255.0f + 0.5f);
- i++;
- }
-}
-FX_LPCBYTE CFX_GEModule::GetTextGammaTable()
-{
- return m_GammaValue;
-}
-void CFX_GEModule::SetExtFontMapper(IFX_FontMapper* pFontMapper)
-{
- GetFontMgr()->m_pExtMapper = pFontMapper;
- pFontMapper->m_pFontMgr = m_pFontMgr;
-}
+// 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 "../../../include/fxge/fx_ge.h"
+#include "text_int.h"
+static CFX_GEModule* g_pGEModule = NULL;
+CFX_GEModule::CFX_GEModule()
+{
+ m_pFontCache = NULL;
+ m_pFontMgr = NULL;
+ m_FTLibrary = NULL;
+ m_pCodecModule = NULL;
+ m_pPlatformData = NULL;
+}
+CFX_GEModule::~CFX_GEModule()
+{
+ if (m_pFontCache) {
+ delete m_pFontCache;
+ }
+ m_pFontCache = NULL;
+ if (m_pFontMgr) {
+ delete m_pFontMgr;
+ }
+ m_pFontMgr = NULL;
+ DestroyPlatform();
+}
+CFX_GEModule* CFX_GEModule::Get()
+{
+ return g_pGEModule;
+}
+void CFX_GEModule::Create()
+{
+ g_pGEModule = FX_NEW CFX_GEModule;
+ if (!g_pGEModule) {
+ return;
+ }
+ g_pGEModule->m_pFontMgr = FX_NEW CFX_FontMgr;
+ g_pGEModule->InitPlatform();
+ g_pGEModule->SetTextGamma(2.2f);
+}
+void CFX_GEModule::Use(CFX_GEModule* pModule)
+{
+ g_pGEModule = pModule;
+}
+void CFX_GEModule::Destroy()
+{
+ if (g_pGEModule) {
+ delete g_pGEModule;
+ }
+ g_pGEModule = NULL;
+}
+CFX_FontCache* CFX_GEModule::GetFontCache()
+{
+ if (m_pFontCache == NULL) {
+ m_pFontCache = FX_NEW CFX_FontCache();
+ }
+ return m_pFontCache;
+}
+void CFX_GEModule::SetTextGamma(FX_FLOAT gammaValue)
+{
+ gammaValue /= 2.2f;
+ int i = 0;
+ while (i < 256) {
+ m_GammaValue[i] = (FX_BYTE)(FXSYS_pow((FX_FLOAT)i / 255, gammaValue) * 255.0f + 0.5f);
+ i++;
+ }
+}
+FX_LPCBYTE CFX_GEModule::GetTextGammaTable()
+{
+ return m_GammaValue;
+}
+void CFX_GEModule::SetExtFontMapper(IFX_FontMapper* pFontMapper)
+{
+ GetFontMgr()->m_pExtMapper = pFontMapper;
+ pFontMapper->m_pFontMgr = m_pFontMgr;
+}
diff --git a/core/src/fxge/ge/fx_ge_device.cpp b/core/src/fxge/ge/fx_ge_device.cpp
index 8f7ccdb7d9..9c268b5606 100644
--- a/core/src/fxge/ge/fx_ge_device.cpp
+++ b/core/src/fxge/ge/fx_ge_device.cpp
@@ -1,405 +1,405 @@
-// 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 "../../../include/fxge/fx_ge.h"
-CFX_RenderDevice::CFX_RenderDevice()
-{
- m_pDeviceDriver = NULL;
- m_pBitmap = NULL;
-}
-CFX_RenderDevice::~CFX_RenderDevice()
-{
- if (m_pDeviceDriver) {
- delete m_pDeviceDriver;
- }
-}
-void CFX_RenderDevice::SetDeviceDriver(IFX_RenderDeviceDriver* pDriver)
-{
- if (m_pDeviceDriver) {
- delete m_pDeviceDriver;
- }
- m_pDeviceDriver = pDriver;
- InitDeviceInfo();
-}
-void CFX_RenderDevice::InitDeviceInfo()
-{
- ASSERT(m_pDeviceDriver != NULL);
- m_Width = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_WIDTH);
- m_Height = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_HEIGHT);
- m_bpp = m_pDeviceDriver->GetDeviceCaps(FXDC_BITS_PIXEL);
- m_RenderCaps = m_pDeviceDriver->GetDeviceCaps(FXDC_RENDER_CAPS);
- m_DeviceClass = m_pDeviceDriver->GetDeviceCaps(FXDC_DEVICE_CLASS);
- if (!m_pDeviceDriver->GetClipBox(&m_ClipBox)) {
- m_ClipBox.left = 0;
- m_ClipBox.top = 0;
- m_ClipBox.right = m_Width;
- m_ClipBox.bottom = m_Height;
- }
-}
-FX_BOOL CFX_RenderDevice::StartRendering()
-{
- return m_pDeviceDriver->StartRendering();
-}
-void CFX_RenderDevice::EndRendering()
-{
- m_pDeviceDriver->EndRendering();
-}
-void CFX_RenderDevice::SaveState()
-{
- m_pDeviceDriver->SaveState();
-}
-void CFX_RenderDevice::RestoreState(FX_BOOL bKeepSaved)
-{
- m_pDeviceDriver->RestoreState(bKeepSaved);
- UpdateClipBox();
-}
-int CFX_RenderDevice::GetDeviceCaps(int caps_id) const
-{
- return m_pDeviceDriver->GetDeviceCaps(caps_id);
-}
-CFX_Matrix CFX_RenderDevice::GetCTM() const
-{
- return m_pDeviceDriver->GetCTM();
-}
-FX_BOOL CFX_RenderDevice::CreateCompatibleBitmap(CFX_DIBitmap* pDIB, int width, int height) const
-{
- if (m_RenderCaps & FXRC_CMYK_OUTPUT) {
- return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Cmyka : FXDIB_Cmyk);
- } else if (m_RenderCaps & FXRC_BYTEMASK_OUTPUT) {
- return pDIB->Create(width, height, FXDIB_8bppMask);
- } else
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Argb : FXDIB_Rgb32);
-#else
- return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Argb : FXDIB_Rgb);
-#endif
-}
-FX_BOOL CFX_RenderDevice::SetClip_PathFill(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- int fill_mode
- )
-{
- if (!m_pDeviceDriver->SetClip_PathFill(pPathData, pObject2Device, fill_mode)) {
- return FALSE;
- }
- UpdateClipBox();
- return TRUE;
-}
-FX_BOOL CFX_RenderDevice::SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState
- )
-{
- if (!m_pDeviceDriver->SetClip_PathStroke(pPathData, pObject2Device, pGraphState)) {
- return FALSE;
- }
- UpdateClipBox();
- return TRUE;
-}
-FX_BOOL CFX_RenderDevice::SetClip_Rect(const FX_RECT* pRect)
-{
- CFX_PathData path;
- path.AppendRect((FX_FLOAT)(pRect->left), (FX_FLOAT)(pRect->bottom), (FX_FLOAT)(pRect->right), (FX_FLOAT)(pRect->top));
- if (!SetClip_PathFill(&path, NULL, FXFILL_WINDING)) {
- return FALSE;
- }
- UpdateClipBox();
- return TRUE;
-}
-void CFX_RenderDevice::UpdateClipBox()
-{
- if (m_pDeviceDriver->GetClipBox(&m_ClipBox)) {
- return;
- }
- m_ClipBox.left = 0;
- m_ClipBox.top = 0;
- m_ClipBox.right = m_Width;
- m_ClipBox.bottom = m_Height;
-}
-FX_BOOL CFX_RenderDevice::DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color, FX_DWORD stroke_color, int fill_mode,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- FX_BYTE fill_alpha, stroke_alpha;
- if (FXGETFLAG_COLORTYPE(alpha_flag)) {
- fill_alpha = FXGETFLAG_ALPHA_FILL(alpha_flag);
- stroke_alpha = FXGETFLAG_ALPHA_STROKE(alpha_flag);
- } else {
- fill_alpha = FXARGB_A(fill_color);
- stroke_alpha = FXARGB_A(stroke_color);
- }
- if ((fill_mode & 3) == 0) {
- fill_alpha = 0;
- }
- if (pGraphState == NULL) {
- stroke_alpha = 0;
- }
- if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) {
- FX_PATHPOINT* pPoints = pPathData->GetPoints();
- FX_FLOAT x1, x2, y1, y2;
- if (pObject2Device) {
- pObject2Device->Transform(pPoints[0].m_PointX, pPoints[0].m_PointY, x1, y1);
- pObject2Device->Transform(pPoints[1].m_PointX, pPoints[1].m_PointY, x2, y2);
- } else {
- x1 = pPoints[0].m_PointX;
- y1 = pPoints[0].m_PointY;
- x2 = pPoints[1].m_PointX;
- y2 = pPoints[1].m_PointY;
- }
- DrawCosmeticLine(x1, y1, x2, y2, fill_color, fill_mode, alpha_flag, pIccTransform, blend_type);
- return TRUE;
- }
- if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) && stroke_alpha == 0) {
- CFX_FloatRect rect_f;
- if (!(fill_mode & FXFILL_RECT_AA) && pPathData->IsRect(pObject2Device, &rect_f)) {
- FX_RECT rect_i = rect_f.GetOutterRect();
- int width = (int)FXSYS_ceil(rect_f.right - rect_f.left);
- if (width < 1) {
- width = 1;
- if (rect_i.left == rect_i.right) {
- rect_i.right ++;
- }
- }
- int height = (int)FXSYS_ceil(rect_f.top - rect_f.bottom);
- if (height < 1) {
- height = 1;
- if (rect_i.bottom == rect_i.top) {
- rect_i.bottom ++;
- }
- }
- if (rect_i.Width() >= width + 1) {
- if (rect_f.left - (FX_FLOAT)(rect_i.left) > (FX_FLOAT)(rect_i.right) - rect_f.right) {
- rect_i.left ++;
- } else {
- rect_i.right --;
- }
- }
- if (rect_i.Height() >= height + 1) {
- if (rect_f.top - (FX_FLOAT)(rect_i.top) > (FX_FLOAT)(rect_i.bottom) - rect_f.bottom) {
- rect_i.top ++;
- } else {
- rect_i.bottom --;
- }
- }
- if (FillRect(&rect_i, fill_color, alpha_flag, pIccTransform, blend_type)) {
- return TRUE;
- }
- }
- }
- if((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) && !(fill_mode & FX_FILL_TEXT_MODE)) {
- CFX_PathData newPath;
- FX_BOOL bThin = FALSE;
- if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin, m_pDeviceDriver->GetDriverType())) {
- CFX_GraphStateData graphState;
- graphState.m_LineWidth = 0.0f;
- FX_DWORD strokecolor = fill_color;
- if (bThin) {
- if (FXGETFLAG_COLORTYPE(alpha_flag)) {
- FXSETFLAG_ALPHA_STROKE(alpha_flag, fill_alpha >> 2);
- } else {
- strokecolor = (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff));
- }
- }
- CFX_AffineMatrix* pMatrix = NULL;
- if (pObject2Device && !pObject2Device->IsIdentity()) {
- pMatrix = (CFX_AffineMatrix*)pObject2Device;
- }
- int smooth_path = FX_ZEROAREA_FILL;
- if (fill_mode & FXFILL_NOPATHSMOOTH) {
- smooth_path |= FXFILL_NOPATHSMOOTH;
- }
- m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor, smooth_path, alpha_flag, pIccTransform, blend_type);
- }
- }
- if ((fill_mode & 3) && fill_alpha && stroke_alpha < 0xff && (fill_mode & FX_FILL_STROKE)) {
- if (!(m_RenderCaps & FXRC_GET_BITS)) {
- return FALSE;
- }
- CFX_FloatRect bbox;
- if (pGraphState) {
- bbox = pPathData->GetBoundingBox(pGraphState->m_LineWidth, pGraphState->m_MiterLimit);
- } else {
- bbox = pPathData->GetBoundingBox();
- }
- if (pObject2Device) {
- bbox.Transform(pObject2Device);
- }
- CFX_Matrix ctm = GetCTM();
- FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
- FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
- FX_RECT rect = bbox.GetOutterRect();
- CFX_DIBitmap bitmap, Backdrop;
- if (!CreateCompatibleBitmap(&bitmap, FXSYS_round(rect.Width() * fScaleX), FXSYS_round(rect.Height() * fScaleY))) {
- return FALSE;
- }
- if (bitmap.HasAlpha()) {
- bitmap.Clear(0);
- Backdrop.Copy(&bitmap);
- } else {
- if (!m_pDeviceDriver->GetDIBits(&bitmap, rect.left, rect.top, NULL)) {
- return FALSE;
- }
- Backdrop.Copy(&bitmap);
- }
- CFX_FxgeDevice bitmap_device;
- bitmap_device.Attach(&bitmap, 0, FALSE, &Backdrop, TRUE);
- CFX_AffineMatrix matrix;
- if (pObject2Device) {
- matrix = *pObject2Device;
- }
- matrix.TranslateI(-rect.left, -rect.top);
- matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0);
- if (!bitmap_device.GetDeviceDriver()->DrawPath(pPathData, &matrix, pGraphState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type)) {
- return FALSE;
- }
- FX_RECT src_rect(0, 0, FXSYS_round(rect.Width() * fScaleX), FXSYS_round(rect.Height() * fScaleY));
- return m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, rect.left, rect.top, FXDIB_BLEND_NORMAL);
- }
- return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type);
-}
-FX_BOOL CFX_RenderDevice::SetPixel(int x, int y, FX_DWORD color, int alpha_flag, void* pIccTransform)
-{
- if (m_pDeviceDriver->SetPixel(x, y, color, alpha_flag, pIccTransform)) {
- return TRUE;
- }
- FX_RECT rect(x, y, x + 1, y + 1);
- return FillRect(&rect, color, alpha_flag, pIccTransform);
-}
-FX_BOOL CFX_RenderDevice::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (m_pDeviceDriver->FillRect(pRect, fill_color, alpha_flag, pIccTransform, blend_type)) {
- return TRUE;
- }
- if (!(m_RenderCaps & FXRC_GET_BITS)) {
- return FALSE;
- }
- CFX_DIBitmap bitmap;
- if (!CreateCompatibleBitmap(&bitmap, pRect->Width(), pRect->Height())) {
- return FALSE;
- }
- if (!m_pDeviceDriver->GetDIBits(&bitmap, pRect->left, pRect->top)) {
- return FALSE;
- }
- if (!bitmap.CompositeRect(0, 0, pRect->Width(), pRect->Height(), fill_color, alpha_flag, pIccTransform)) {
- return FALSE;
- }
- FX_RECT src_rect(0, 0, pRect->Width(), pRect->Height());
- m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, pRect->left, pRect->top, FXDIB_BLEND_NORMAL);
- return TRUE;
-}
-FX_BOOL CFX_RenderDevice::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
- int fill_mode, int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (((m_RenderCaps & FXRC_ALPHA_PATH) &&
- (FXGETFLAG_COLORTYPE(alpha_flag) && FXGETFLAG_ALPHA_FILL(alpha_flag) == 0xff)) ||
- color >= 0xff000000)
- if (m_pDeviceDriver->DrawCosmeticLine(x1, y1, x2, y2, color, alpha_flag, pIccTransform, blend_type)) {
- return TRUE;
- }
- CFX_GraphStateData graph_state;
- CFX_PathData path;
- path.SetPointCount(2);
- path.SetPoint(0, x1, y1, FXPT_MOVETO);
- path.SetPoint(1, x2, y2, FXPT_LINETO);
- return m_pDeviceDriver->DrawPath(&path, NULL, &graph_state, 0, color, fill_mode, alpha_flag, pIccTransform, blend_type);
-}
-FX_BOOL CFX_RenderDevice::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform)
-{
- if (!(m_RenderCaps & FXRC_GET_BITS)) {
- return FALSE;
- }
- return m_pDeviceDriver->GetDIBits(pBitmap, left, top, pIccTransform);
-}
-CFX_DIBitmap* CFX_RenderDevice::GetBackDrop()
-{
- return m_pDeviceDriver->GetBackDrop();
-}
-FX_BOOL CFX_RenderDevice::SetDIBits(const CFX_DIBSource* pBitmap, int left, int top, int blend_mode,
- void* pIccTransform)
-{
- ASSERT(!pBitmap->IsAlphaMask());
- CFX_AffineMatrix ctm = GetCTM();
- FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
- FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
- FX_RECT dest_rect(left, top, FXSYS_round(left + pBitmap->GetWidth() / fScaleX), FXSYS_round(top + pBitmap->GetHeight() / fScaleY));
- dest_rect.Intersect(m_ClipBox);
- if (dest_rect.IsEmpty()) {
- return TRUE;
- }
- FX_RECT src_rect(dest_rect.left - left, dest_rect.top - top,
- dest_rect.left - left + dest_rect.Width(), dest_rect.top - top + dest_rect.Height());
- src_rect.left = FXSYS_round(src_rect.left * fScaleX);
- src_rect.top = FXSYS_round(src_rect.top * fScaleY);
- src_rect.right = FXSYS_round(src_rect.right * fScaleX);
- src_rect.bottom = FXSYS_round(src_rect.bottom * fScaleY);
- if ((blend_mode != FXDIB_BLEND_NORMAL && !(m_RenderCaps & FXRC_BLEND_MODE)) ||
- (pBitmap->HasAlpha() && !(m_RenderCaps & FXRC_ALPHA_IMAGE))) {
- if (!(m_RenderCaps & FXRC_GET_BITS)) {
- return FALSE;
- }
- int bg_pixel_width = FXSYS_round(dest_rect.Width() * fScaleX);
- int bg_pixel_height = FXSYS_round(dest_rect.Height() * fScaleY);
- CFX_DIBitmap background;
- if (!background.Create(bg_pixel_width, bg_pixel_height,
- (m_RenderCaps & FXRC_CMYK_OUTPUT) ? FXDIB_Cmyk : FXDIB_Rgb32)) {
- return FALSE;
- }
- if (!m_pDeviceDriver->GetDIBits(&background, dest_rect.left, dest_rect.top)) {
- return FALSE;
- }
- if (!background.CompositeBitmap(0, 0, bg_pixel_width, bg_pixel_height,
- pBitmap, src_rect.left, src_rect.top,
- blend_mode, NULL, FALSE, pIccTransform)) {
- return FALSE;
- }
- FX_RECT src_rect(0, 0, bg_pixel_width, bg_pixel_height);
- return m_pDeviceDriver->SetDIBits(&background, 0, &src_rect, dest_rect.left, dest_rect.top, FXDIB_BLEND_NORMAL);
- }
- return m_pDeviceDriver->SetDIBits(pBitmap, 0, &src_rect, dest_rect.left, dest_rect.top, blend_mode, 0, pIccTransform);
-}
-FX_BOOL CFX_RenderDevice::StretchDIBits(const CFX_DIBSource* pBitmap, int left, int top,
- int dest_width, int dest_height, FX_DWORD flags,
- void* pIccTransform, int blend_mode)
-{
- FX_RECT dest_rect(left, top, left + dest_width, top + dest_height);
- FX_RECT clip_box = m_ClipBox;
- clip_box.Intersect(dest_rect);
- if (clip_box.IsEmpty()) {
- return TRUE;
- }
- return m_pDeviceDriver->StretchDIBits(pBitmap, 0, left, top, dest_width, dest_height, &clip_box, flags, 0, pIccTransform, blend_mode);
-}
-FX_BOOL CFX_RenderDevice::SetBitMask(const CFX_DIBSource* pBitmap, int left, int top, FX_DWORD argb,
- int alpha_flag, void* pIccTransform)
-{
- FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
- return m_pDeviceDriver->SetDIBits(pBitmap, argb, &src_rect, left, top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform);
-}
-FX_BOOL CFX_RenderDevice::StretchBitMask(const CFX_DIBSource* pBitmap, int left, int top,
- int dest_width, int dest_height, FX_DWORD argb, FX_DWORD flags,
- int alpha_flag, void* pIccTransform)
-{
- FX_RECT dest_rect(left, top, left + dest_width, top + dest_height);
- FX_RECT clip_box = m_ClipBox;
- clip_box.Intersect(dest_rect);
- return m_pDeviceDriver->StretchDIBits(pBitmap, argb, left, top, dest_width, dest_height, &clip_box, flags, alpha_flag, pIccTransform);
-}
-FX_BOOL CFX_RenderDevice::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD argb,
- const CFX_AffineMatrix* pMatrix, FX_DWORD flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_mode)
-{
- return m_pDeviceDriver->StartDIBits(pBitmap, bitmap_alpha, argb, pMatrix, flags, handle, alpha_flag, pIccTransform, blend_mode);
-}
-FX_BOOL CFX_RenderDevice::ContinueDIBits(FX_LPVOID handle, IFX_Pause* pPause)
-{
- return m_pDeviceDriver->ContinueDIBits(handle, pPause);
-}
-void CFX_RenderDevice::CancelDIBits(FX_LPVOID handle)
-{
- m_pDeviceDriver->CancelDIBits(handle);
-}
+// 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 "../../../include/fxge/fx_ge.h"
+CFX_RenderDevice::CFX_RenderDevice()
+{
+ m_pDeviceDriver = NULL;
+ m_pBitmap = NULL;
+}
+CFX_RenderDevice::~CFX_RenderDevice()
+{
+ if (m_pDeviceDriver) {
+ delete m_pDeviceDriver;
+ }
+}
+void CFX_RenderDevice::SetDeviceDriver(IFX_RenderDeviceDriver* pDriver)
+{
+ if (m_pDeviceDriver) {
+ delete m_pDeviceDriver;
+ }
+ m_pDeviceDriver = pDriver;
+ InitDeviceInfo();
+}
+void CFX_RenderDevice::InitDeviceInfo()
+{
+ ASSERT(m_pDeviceDriver != NULL);
+ m_Width = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_WIDTH);
+ m_Height = m_pDeviceDriver->GetDeviceCaps(FXDC_PIXEL_HEIGHT);
+ m_bpp = m_pDeviceDriver->GetDeviceCaps(FXDC_BITS_PIXEL);
+ m_RenderCaps = m_pDeviceDriver->GetDeviceCaps(FXDC_RENDER_CAPS);
+ m_DeviceClass = m_pDeviceDriver->GetDeviceCaps(FXDC_DEVICE_CLASS);
+ if (!m_pDeviceDriver->GetClipBox(&m_ClipBox)) {
+ m_ClipBox.left = 0;
+ m_ClipBox.top = 0;
+ m_ClipBox.right = m_Width;
+ m_ClipBox.bottom = m_Height;
+ }
+}
+FX_BOOL CFX_RenderDevice::StartRendering()
+{
+ return m_pDeviceDriver->StartRendering();
+}
+void CFX_RenderDevice::EndRendering()
+{
+ m_pDeviceDriver->EndRendering();
+}
+void CFX_RenderDevice::SaveState()
+{
+ m_pDeviceDriver->SaveState();
+}
+void CFX_RenderDevice::RestoreState(FX_BOOL bKeepSaved)
+{
+ m_pDeviceDriver->RestoreState(bKeepSaved);
+ UpdateClipBox();
+}
+int CFX_RenderDevice::GetDeviceCaps(int caps_id) const
+{
+ return m_pDeviceDriver->GetDeviceCaps(caps_id);
+}
+CFX_Matrix CFX_RenderDevice::GetCTM() const
+{
+ return m_pDeviceDriver->GetCTM();
+}
+FX_BOOL CFX_RenderDevice::CreateCompatibleBitmap(CFX_DIBitmap* pDIB, int width, int height) const
+{
+ if (m_RenderCaps & FXRC_CMYK_OUTPUT) {
+ return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Cmyka : FXDIB_Cmyk);
+ } else if (m_RenderCaps & FXRC_BYTEMASK_OUTPUT) {
+ return pDIB->Create(width, height, FXDIB_8bppMask);
+ } else
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Argb : FXDIB_Rgb32);
+#else
+ return pDIB->Create(width, height, m_RenderCaps & FXRC_ALPHA_OUTPUT ? FXDIB_Argb : FXDIB_Rgb);
+#endif
+}
+FX_BOOL CFX_RenderDevice::SetClip_PathFill(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ int fill_mode
+ )
+{
+ if (!m_pDeviceDriver->SetClip_PathFill(pPathData, pObject2Device, fill_mode)) {
+ return FALSE;
+ }
+ UpdateClipBox();
+ return TRUE;
+}
+FX_BOOL CFX_RenderDevice::SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState
+ )
+{
+ if (!m_pDeviceDriver->SetClip_PathStroke(pPathData, pObject2Device, pGraphState)) {
+ return FALSE;
+ }
+ UpdateClipBox();
+ return TRUE;
+}
+FX_BOOL CFX_RenderDevice::SetClip_Rect(const FX_RECT* pRect)
+{
+ CFX_PathData path;
+ path.AppendRect((FX_FLOAT)(pRect->left), (FX_FLOAT)(pRect->bottom), (FX_FLOAT)(pRect->right), (FX_FLOAT)(pRect->top));
+ if (!SetClip_PathFill(&path, NULL, FXFILL_WINDING)) {
+ return FALSE;
+ }
+ UpdateClipBox();
+ return TRUE;
+}
+void CFX_RenderDevice::UpdateClipBox()
+{
+ if (m_pDeviceDriver->GetClipBox(&m_ClipBox)) {
+ return;
+ }
+ m_ClipBox.left = 0;
+ m_ClipBox.top = 0;
+ m_ClipBox.right = m_Width;
+ m_ClipBox.bottom = m_Height;
+}
+FX_BOOL CFX_RenderDevice::DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color, FX_DWORD stroke_color, int fill_mode,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ FX_BYTE fill_alpha, stroke_alpha;
+ if (FXGETFLAG_COLORTYPE(alpha_flag)) {
+ fill_alpha = FXGETFLAG_ALPHA_FILL(alpha_flag);
+ stroke_alpha = FXGETFLAG_ALPHA_STROKE(alpha_flag);
+ } else {
+ fill_alpha = FXARGB_A(fill_color);
+ stroke_alpha = FXARGB_A(stroke_color);
+ }
+ if ((fill_mode & 3) == 0) {
+ fill_alpha = 0;
+ }
+ if (pGraphState == NULL) {
+ stroke_alpha = 0;
+ }
+ if (stroke_alpha == 0 && pPathData->GetPointCount() == 2) {
+ FX_PATHPOINT* pPoints = pPathData->GetPoints();
+ FX_FLOAT x1, x2, y1, y2;
+ if (pObject2Device) {
+ pObject2Device->Transform(pPoints[0].m_PointX, pPoints[0].m_PointY, x1, y1);
+ pObject2Device->Transform(pPoints[1].m_PointX, pPoints[1].m_PointY, x2, y2);
+ } else {
+ x1 = pPoints[0].m_PointX;
+ y1 = pPoints[0].m_PointY;
+ x2 = pPoints[1].m_PointX;
+ y2 = pPoints[1].m_PointY;
+ }
+ DrawCosmeticLine(x1, y1, x2, y2, fill_color, fill_mode, alpha_flag, pIccTransform, blend_type);
+ return TRUE;
+ }
+ if ((pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) && stroke_alpha == 0) {
+ CFX_FloatRect rect_f;
+ if (!(fill_mode & FXFILL_RECT_AA) && pPathData->IsRect(pObject2Device, &rect_f)) {
+ FX_RECT rect_i = rect_f.GetOutterRect();
+ int width = (int)FXSYS_ceil(rect_f.right - rect_f.left);
+ if (width < 1) {
+ width = 1;
+ if (rect_i.left == rect_i.right) {
+ rect_i.right ++;
+ }
+ }
+ int height = (int)FXSYS_ceil(rect_f.top - rect_f.bottom);
+ if (height < 1) {
+ height = 1;
+ if (rect_i.bottom == rect_i.top) {
+ rect_i.bottom ++;
+ }
+ }
+ if (rect_i.Width() >= width + 1) {
+ if (rect_f.left - (FX_FLOAT)(rect_i.left) > (FX_FLOAT)(rect_i.right) - rect_f.right) {
+ rect_i.left ++;
+ } else {
+ rect_i.right --;
+ }
+ }
+ if (rect_i.Height() >= height + 1) {
+ if (rect_f.top - (FX_FLOAT)(rect_i.top) > (FX_FLOAT)(rect_i.bottom) - rect_f.bottom) {
+ rect_i.top ++;
+ } else {
+ rect_i.bottom --;
+ }
+ }
+ if (FillRect(&rect_i, fill_color, alpha_flag, pIccTransform, blend_type)) {
+ return TRUE;
+ }
+ }
+ }
+ if((fill_mode & 3) && stroke_alpha == 0 && !(fill_mode & FX_FILL_STROKE) && !(fill_mode & FX_FILL_TEXT_MODE)) {
+ CFX_PathData newPath;
+ FX_BOOL bThin = FALSE;
+ if (pPathData->GetZeroAreaPath(newPath, (CFX_Matrix*)pObject2Device, bThin, m_pDeviceDriver->GetDriverType())) {
+ CFX_GraphStateData graphState;
+ graphState.m_LineWidth = 0.0f;
+ FX_DWORD strokecolor = fill_color;
+ if (bThin) {
+ if (FXGETFLAG_COLORTYPE(alpha_flag)) {
+ FXSETFLAG_ALPHA_STROKE(alpha_flag, fill_alpha >> 2);
+ } else {
+ strokecolor = (((fill_alpha >> 2) << 24) | (strokecolor & 0x00ffffff));
+ }
+ }
+ CFX_AffineMatrix* pMatrix = NULL;
+ if (pObject2Device && !pObject2Device->IsIdentity()) {
+ pMatrix = (CFX_AffineMatrix*)pObject2Device;
+ }
+ int smooth_path = FX_ZEROAREA_FILL;
+ if (fill_mode & FXFILL_NOPATHSMOOTH) {
+ smooth_path |= FXFILL_NOPATHSMOOTH;
+ }
+ m_pDeviceDriver->DrawPath(&newPath, pMatrix, &graphState, 0, strokecolor, smooth_path, alpha_flag, pIccTransform, blend_type);
+ }
+ }
+ if ((fill_mode & 3) && fill_alpha && stroke_alpha < 0xff && (fill_mode & FX_FILL_STROKE)) {
+ if (!(m_RenderCaps & FXRC_GET_BITS)) {
+ return FALSE;
+ }
+ CFX_FloatRect bbox;
+ if (pGraphState) {
+ bbox = pPathData->GetBoundingBox(pGraphState->m_LineWidth, pGraphState->m_MiterLimit);
+ } else {
+ bbox = pPathData->GetBoundingBox();
+ }
+ if (pObject2Device) {
+ bbox.Transform(pObject2Device);
+ }
+ CFX_Matrix ctm = GetCTM();
+ FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
+ FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
+ FX_RECT rect = bbox.GetOutterRect();
+ CFX_DIBitmap bitmap, Backdrop;
+ if (!CreateCompatibleBitmap(&bitmap, FXSYS_round(rect.Width() * fScaleX), FXSYS_round(rect.Height() * fScaleY))) {
+ return FALSE;
+ }
+ if (bitmap.HasAlpha()) {
+ bitmap.Clear(0);
+ Backdrop.Copy(&bitmap);
+ } else {
+ if (!m_pDeviceDriver->GetDIBits(&bitmap, rect.left, rect.top, NULL)) {
+ return FALSE;
+ }
+ Backdrop.Copy(&bitmap);
+ }
+ CFX_FxgeDevice bitmap_device;
+ bitmap_device.Attach(&bitmap, 0, FALSE, &Backdrop, TRUE);
+ CFX_AffineMatrix matrix;
+ if (pObject2Device) {
+ matrix = *pObject2Device;
+ }
+ matrix.TranslateI(-rect.left, -rect.top);
+ matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0);
+ if (!bitmap_device.GetDeviceDriver()->DrawPath(pPathData, &matrix, pGraphState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type)) {
+ return FALSE;
+ }
+ FX_RECT src_rect(0, 0, FXSYS_round(rect.Width() * fScaleX), FXSYS_round(rect.Height() * fScaleY));
+ return m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, rect.left, rect.top, FXDIB_BLEND_NORMAL);
+ }
+ return m_pDeviceDriver->DrawPath(pPathData, pObject2Device, pGraphState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type);
+}
+FX_BOOL CFX_RenderDevice::SetPixel(int x, int y, FX_DWORD color, int alpha_flag, void* pIccTransform)
+{
+ if (m_pDeviceDriver->SetPixel(x, y, color, alpha_flag, pIccTransform)) {
+ return TRUE;
+ }
+ FX_RECT rect(x, y, x + 1, y + 1);
+ return FillRect(&rect, color, alpha_flag, pIccTransform);
+}
+FX_BOOL CFX_RenderDevice::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (m_pDeviceDriver->FillRect(pRect, fill_color, alpha_flag, pIccTransform, blend_type)) {
+ return TRUE;
+ }
+ if (!(m_RenderCaps & FXRC_GET_BITS)) {
+ return FALSE;
+ }
+ CFX_DIBitmap bitmap;
+ if (!CreateCompatibleBitmap(&bitmap, pRect->Width(), pRect->Height())) {
+ return FALSE;
+ }
+ if (!m_pDeviceDriver->GetDIBits(&bitmap, pRect->left, pRect->top)) {
+ return FALSE;
+ }
+ if (!bitmap.CompositeRect(0, 0, pRect->Width(), pRect->Height(), fill_color, alpha_flag, pIccTransform)) {
+ return FALSE;
+ }
+ FX_RECT src_rect(0, 0, pRect->Width(), pRect->Height());
+ m_pDeviceDriver->SetDIBits(&bitmap, 0, &src_rect, pRect->left, pRect->top, FXDIB_BLEND_NORMAL);
+ return TRUE;
+}
+FX_BOOL CFX_RenderDevice::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
+ int fill_mode, int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (((m_RenderCaps & FXRC_ALPHA_PATH) &&
+ (FXGETFLAG_COLORTYPE(alpha_flag) && FXGETFLAG_ALPHA_FILL(alpha_flag) == 0xff)) ||
+ color >= 0xff000000)
+ if (m_pDeviceDriver->DrawCosmeticLine(x1, y1, x2, y2, color, alpha_flag, pIccTransform, blend_type)) {
+ return TRUE;
+ }
+ CFX_GraphStateData graph_state;
+ CFX_PathData path;
+ path.SetPointCount(2);
+ path.SetPoint(0, x1, y1, FXPT_MOVETO);
+ path.SetPoint(1, x2, y2, FXPT_LINETO);
+ return m_pDeviceDriver->DrawPath(&path, NULL, &graph_state, 0, color, fill_mode, alpha_flag, pIccTransform, blend_type);
+}
+FX_BOOL CFX_RenderDevice::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform)
+{
+ if (!(m_RenderCaps & FXRC_GET_BITS)) {
+ return FALSE;
+ }
+ return m_pDeviceDriver->GetDIBits(pBitmap, left, top, pIccTransform);
+}
+CFX_DIBitmap* CFX_RenderDevice::GetBackDrop()
+{
+ return m_pDeviceDriver->GetBackDrop();
+}
+FX_BOOL CFX_RenderDevice::SetDIBits(const CFX_DIBSource* pBitmap, int left, int top, int blend_mode,
+ void* pIccTransform)
+{
+ ASSERT(!pBitmap->IsAlphaMask());
+ CFX_AffineMatrix ctm = GetCTM();
+ FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
+ FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
+ FX_RECT dest_rect(left, top, FXSYS_round(left + pBitmap->GetWidth() / fScaleX), FXSYS_round(top + pBitmap->GetHeight() / fScaleY));
+ dest_rect.Intersect(m_ClipBox);
+ if (dest_rect.IsEmpty()) {
+ return TRUE;
+ }
+ FX_RECT src_rect(dest_rect.left - left, dest_rect.top - top,
+ dest_rect.left - left + dest_rect.Width(), dest_rect.top - top + dest_rect.Height());
+ src_rect.left = FXSYS_round(src_rect.left * fScaleX);
+ src_rect.top = FXSYS_round(src_rect.top * fScaleY);
+ src_rect.right = FXSYS_round(src_rect.right * fScaleX);
+ src_rect.bottom = FXSYS_round(src_rect.bottom * fScaleY);
+ if ((blend_mode != FXDIB_BLEND_NORMAL && !(m_RenderCaps & FXRC_BLEND_MODE)) ||
+ (pBitmap->HasAlpha() && !(m_RenderCaps & FXRC_ALPHA_IMAGE))) {
+ if (!(m_RenderCaps & FXRC_GET_BITS)) {
+ return FALSE;
+ }
+ int bg_pixel_width = FXSYS_round(dest_rect.Width() * fScaleX);
+ int bg_pixel_height = FXSYS_round(dest_rect.Height() * fScaleY);
+ CFX_DIBitmap background;
+ if (!background.Create(bg_pixel_width, bg_pixel_height,
+ (m_RenderCaps & FXRC_CMYK_OUTPUT) ? FXDIB_Cmyk : FXDIB_Rgb32)) {
+ return FALSE;
+ }
+ if (!m_pDeviceDriver->GetDIBits(&background, dest_rect.left, dest_rect.top)) {
+ return FALSE;
+ }
+ if (!background.CompositeBitmap(0, 0, bg_pixel_width, bg_pixel_height,
+ pBitmap, src_rect.left, src_rect.top,
+ blend_mode, NULL, FALSE, pIccTransform)) {
+ return FALSE;
+ }
+ FX_RECT src_rect(0, 0, bg_pixel_width, bg_pixel_height);
+ return m_pDeviceDriver->SetDIBits(&background, 0, &src_rect, dest_rect.left, dest_rect.top, FXDIB_BLEND_NORMAL);
+ }
+ return m_pDeviceDriver->SetDIBits(pBitmap, 0, &src_rect, dest_rect.left, dest_rect.top, blend_mode, 0, pIccTransform);
+}
+FX_BOOL CFX_RenderDevice::StretchDIBits(const CFX_DIBSource* pBitmap, int left, int top,
+ int dest_width, int dest_height, FX_DWORD flags,
+ void* pIccTransform, int blend_mode)
+{
+ FX_RECT dest_rect(left, top, left + dest_width, top + dest_height);
+ FX_RECT clip_box = m_ClipBox;
+ clip_box.Intersect(dest_rect);
+ if (clip_box.IsEmpty()) {
+ return TRUE;
+ }
+ return m_pDeviceDriver->StretchDIBits(pBitmap, 0, left, top, dest_width, dest_height, &clip_box, flags, 0, pIccTransform, blend_mode);
+}
+FX_BOOL CFX_RenderDevice::SetBitMask(const CFX_DIBSource* pBitmap, int left, int top, FX_DWORD argb,
+ int alpha_flag, void* pIccTransform)
+{
+ FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
+ return m_pDeviceDriver->SetDIBits(pBitmap, argb, &src_rect, left, top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform);
+}
+FX_BOOL CFX_RenderDevice::StretchBitMask(const CFX_DIBSource* pBitmap, int left, int top,
+ int dest_width, int dest_height, FX_DWORD argb, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform)
+{
+ FX_RECT dest_rect(left, top, left + dest_width, top + dest_height);
+ FX_RECT clip_box = m_ClipBox;
+ clip_box.Intersect(dest_rect);
+ return m_pDeviceDriver->StretchDIBits(pBitmap, argb, left, top, dest_width, dest_height, &clip_box, flags, alpha_flag, pIccTransform);
+}
+FX_BOOL CFX_RenderDevice::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD argb,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_mode)
+{
+ return m_pDeviceDriver->StartDIBits(pBitmap, bitmap_alpha, argb, pMatrix, flags, handle, alpha_flag, pIccTransform, blend_mode);
+}
+FX_BOOL CFX_RenderDevice::ContinueDIBits(FX_LPVOID handle, IFX_Pause* pPause)
+{
+ return m_pDeviceDriver->ContinueDIBits(handle, pPause);
+}
+void CFX_RenderDevice::CancelDIBits(FX_LPVOID handle)
+{
+ m_pDeviceDriver->CancelDIBits(handle);
+}
diff --git a/core/src/fxge/ge/fx_ge_font.cpp b/core/src/fxge/ge/fx_ge_font.cpp
index e047d2ecb0..f3254ea3de 100644
--- a/core/src/fxge/ge/fx_ge_font.cpp
+++ b/core/src/fxge/ge/fx_ge_font.cpp
@@ -1,458 +1,458 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#include "../../../include/fxge/fx_freetype.h"
-#include "text_int.h"
-#define EM_ADJUST(em, a) (em == 0?(a): (a)*1000/em)
-extern void _FPDFAPI_GetInternalFontData(int id1, FX_LPCBYTE& data, FX_DWORD& size);
-CFX_Font::CFX_Font()
-{
- m_pSubstFont = NULL;
- m_Face = NULL;
- m_bEmbedded = FALSE;
- m_bVertical = FALSE;
- m_pFontData = NULL;
- m_pFontDataAllocation = NULL;
- m_dwSize = 0;
- m_pOwnedStream = NULL;
- m_pGsubData = NULL;
- m_pPlatformFont = NULL;
- m_pPlatformFontCollection = NULL;
- m_pDwFont = NULL;
- m_hHandle = NULL;
- m_bDwLoaded = FALSE;
-}
-CFX_Font::~CFX_Font()
-{
- if (m_pSubstFont) {
- delete m_pSubstFont;
- m_pSubstFont = NULL;
- }
-#ifdef FOXIT_CHROME_BUILD
- if (m_pFontDataAllocation) {
- FX_Free(m_pFontDataAllocation);
- m_pFontDataAllocation = NULL;
- }
-#endif
- if (m_Face) {
-#ifdef FOXIT_CHROME_BUILD
- FXFT_Library library = FXFT_Get_Face_FreeType(m_Face);
- if (FXFT_Get_Face_External_Stream(m_Face)) {
- FXFT_Clear_Face_External_Stream(m_Face);
- }
-#endif
- if(m_bEmbedded) {
- DeleteFace();
- } else {
- CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face);
- }
- }
- if (m_pOwnedStream) {
- FX_Free(m_pOwnedStream);
- m_pOwnedStream = NULL;
- }
- if (m_pGsubData) {
- FX_Free(m_pGsubData);
- m_pGsubData = NULL;
- }
-#if (_FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && (!defined(_FPDFAPI_MINI_)))
- ReleasePlatformResource();
-#endif
-}
-void CFX_Font::DeleteFace()
-{
- FXFT_Done_Face(m_Face);
- m_Face = NULL;
-}
-FX_BOOL CFX_Font::LoadSubst(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags,
- int weight, int italic_angle, int CharsetCP, FX_BOOL bVertical)
-{
- m_bEmbedded = FALSE;
- m_bVertical = bVertical;
- m_pSubstFont = FX_NEW CFX_SubstFont;
- if (!m_pSubstFont) {
- return FALSE;
- }
- m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont(face_name, bTrueType, flags, weight, italic_angle,
- CharsetCP, m_pSubstFont);
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if(m_pSubstFont->m_ExtHandle) {
- m_pPlatformFont = m_pSubstFont->m_ExtHandle;
- m_pSubstFont->m_ExtHandle = NULL;
- }
-#endif
- if (m_Face) {
- m_pFontData = FXFT_Get_Face_Stream_Base(m_Face);
- m_dwSize = FXFT_Get_Face_Stream_Size(m_Face);
- }
- return TRUE;
-}
-extern "C" {
- unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset,
- unsigned char* buffer, unsigned long count)
- {
- if (count == 0) {
- return 0;
- }
- IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer;
- int res = pFile->ReadBlock(buffer, offset, count);
- if (res) {
- return count;
- }
- return 0;
- }
- void _FTStreamClose(FXFT_Stream stream)
- {
- }
-};
-FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream)
-{
- FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(FX_BYTE, sizeof (FXFT_StreamRec));
- if (!stream1) {
- return FALSE;
- }
- stream1->base = NULL;
- stream1->size = (unsigned long)pFile->GetSize();
- stream1->pos = 0;
- stream1->descriptor.pointer = pFile;
- stream1->close = _FTStreamClose;
- stream1->read = _FTStreamRead;
- FXFT_Open_Args args;
- args.flags = FT_OPEN_STREAM;
- args.stream = stream1;
- if (FXFT_Open_Face(library, &args, 0, Face)) {
- FX_Free(stream1);
- return FALSE;
- }
- if (stream) {
- *stream = stream1;
- }
- return TRUE;
-}
-FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile)
-{
- m_bEmbedded = FALSE;
- FXFT_Library library;
- if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
- FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
- }
- library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
- FXFT_Stream stream = NULL;
- if (!_LoadFile(library, &m_Face, pFile, &stream)) {
- return FALSE;
- }
- m_pOwnedStream = stream;
- FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
- return TRUE;
-}
-int CFX_Font::GetGlyphWidth(FX_DWORD glyph_index)
-{
- if (!m_Face) {
- return 0;
- }
- if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) {
- AdjustMMParams(glyph_index, 0, 0);
- }
- int err = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- if (err) {
- return 0;
- }
- int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriAdvance(m_Face));
- return width;
-}
-static FXFT_Face FT_LoadFont(FX_LPBYTE pData, int size)
-{
- FXFT_Library library;
- if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
- FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
- }
- library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
- FXFT_Face face;
- int error = FXFT_New_Memory_Face(library, pData, size, 0, &face);
- if (error) {
- return NULL;
- }
- error = FXFT_Set_Pixel_Sizes(face, 64, 64);
- if (error) {
- return NULL;
- }
- return face;
-}
-FX_BOOL CFX_Font::LoadEmbedded(FX_LPCBYTE data, FX_DWORD size)
-{
-#ifdef FOXIT_CHROME_BUILD
- m_pFontDataAllocation = FX_Alloc(FX_BYTE, size);
- if (!m_pFontDataAllocation) {
- return FALSE;
- }
- FXSYS_memcpy32(m_pFontDataAllocation, data, size);
- m_Face = FT_LoadFont((FX_LPBYTE)m_pFontDataAllocation, size);
- m_pFontData = (FX_LPBYTE)m_pFontDataAllocation;
-#else
- m_Face = FT_LoadFont((FX_LPBYTE)data, size);
- m_pFontData = (FX_LPBYTE)data;
-#endif
- m_bEmbedded = TRUE;
- m_dwSize = size;
- return m_Face != NULL;
-}
-FX_BOOL CFX_Font::IsTTFont()
-{
- if (m_Face == NULL) {
- return FALSE;
- }
- return FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT;
-}
-int CFX_Font::GetAscent() const
-{
- if (m_Face == NULL) {
- return 0;
- }
- int ascent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Ascender(m_Face));
- return ascent;
-}
-int CFX_Font::GetDescent() const
-{
- if (m_Face == NULL) {
- return 0;
- }
- int descent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Descender(m_Face));
- return descent;
-}
-FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT &bbox)
-{
- if (m_Face == NULL) {
- return FALSE;
- }
- if (FXFT_Is_Face_Tricky(m_Face)) {
- int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72);
- if (error) {
- return FALSE;
- }
- error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- if (error) {
- return FALSE;
- }
- FXFT_BBox cbox;
- FT_Glyph glyph;
- error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph);
- if (error) {
- return FALSE;
- }
- FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
- int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem,
- pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem;
- if (pixel_size_x == 0 || pixel_size_y == 0) {
- bbox.left = cbox.xMin;
- bbox.right = cbox.xMax;
- bbox.top = cbox.yMax;
- bbox.bottom = cbox.yMin;
- } else {
- bbox.left = cbox.xMin * 1000 / pixel_size_x;
- bbox.right = cbox.xMax * 1000 / pixel_size_x;
- bbox.top = cbox.yMax * 1000 / pixel_size_y;
- bbox.bottom = cbox.yMin * 1000 / pixel_size_y;
- }
- if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) {
- bbox.top = FXFT_Get_Face_Ascender(m_Face);
- }
- if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) {
- bbox.bottom = FXFT_Get_Face_Descender(m_Face);
- }
- FT_Done_Glyph(glyph);
- return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0;
- }
- if (FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
- return FALSE;
- }
- int em = FXFT_Get_Face_UnitsPerEM(m_Face);
- if (em == 0) {
- bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face);
- bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face);
- bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face);
- bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face);
- } else {
- bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em;
- bbox.top = (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) * 1000 / em;
- bbox.right = (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) * 1000 / em;
- bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em;
- }
- return TRUE;
-}
-FX_BOOL CFX_Font::IsItalic()
-{
- if (m_Face == NULL) {
- return FALSE;
- }
- FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC;
- if (!ret) {
- CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face));
- str.MakeLower();
- if (str.Find("italic") != -1) {
- ret = TRUE;
- }
- }
- return ret;
-}
-FX_BOOL CFX_Font::IsBold()
-{
- if (m_Face == NULL) {
- return FALSE;
- }
- return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD;
-}
-FX_BOOL CFX_Font::IsFixedWidth()
-{
- if (m_Face == NULL) {
- return FALSE;
- }
- return FXFT_Is_Face_fixedwidth(m_Face);
-}
-CFX_WideString CFX_Font::GetPsName() const
-{
- if (m_Face == NULL) {
- return CFX_WideString();
- }
- CFX_WideString psName = CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face));
- if (psName.IsEmpty()) {
- psName = CFX_WideString::FromLocal("Untitled");
- }
- return psName;
-}
-CFX_ByteString CFX_Font::GetFamilyName() const
-{
- if (m_Face == NULL && m_pSubstFont == NULL) {
- return CFX_ByteString();
- }
- if (m_Face) {
- return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face));
- } else {
- return m_pSubstFont->m_Family;
- }
-}
-CFX_ByteString CFX_Font::GetFaceName() const
-{
- if (m_Face == NULL && m_pSubstFont == NULL) {
- return CFX_ByteString();
- }
- if (m_Face) {
- CFX_ByteString facename;
- CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face));
- facename = GetFamilyName();
- if (facename.IsEmpty()) {
- facename = "Untitled";
- }
- if (!style.IsEmpty() && style != "Regular") {
- facename += " " + style;
- }
- return facename;
- } else {
- return m_pSubstFont->m_Family;
- }
-}
-FX_BOOL CFX_Font::GetBBox(FX_RECT &bbox)
-{
- if (m_Face == NULL) {
- return FALSE;
- }
- int em = FXFT_Get_Face_UnitsPerEM(m_Face);
- if (em == 0) {
- bbox.left = FXFT_Get_Face_xMin(m_Face);
- bbox.bottom = FXFT_Get_Face_yMax(m_Face);
- bbox.top = FXFT_Get_Face_yMin(m_Face);
- bbox.right = FXFT_Get_Face_xMax(m_Face);
- } else {
- bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em;
- bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em;
- bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em;
- bbox.bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em;
- }
- return TRUE;
-}
-int CFX_Font::GetHeight()
-{
- if (m_Face == NULL) {
- return 0;
- }
- int height = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Height(m_Face));
- return height;
-}
-int CFX_Font::GetMaxAdvanceWidth()
-{
- if (m_Face == NULL) {
- return 0;
- }
- int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_MaxAdvanceWidth(m_Face));
- return width;
-}
-int CFX_Font::GetULPos()
-{
- if (m_Face == NULL) {
- return 0;
- }
- int pos = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_UnderLinePosition(m_Face));
- return pos;
-}
-int CFX_Font::GetULthickness()
-{
- if (m_Face == NULL) {
- return 0;
- }
- int thickness = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_UnderLineThickness(m_Face));
- return thickness;
-}
-CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont)
-{
- m_pFont = pFont;
-}
-FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode)
-{
- FXFT_Face face = m_pFont->GetFace();
- if (!face) {
- return charcode;
- }
- if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0) {
- return FXFT_Get_Char_Index(face, charcode);
- }
- if (m_pFont->m_pSubstFont && m_pFont->m_pSubstFont->m_Charset == 2) {
- FX_DWORD index = 0;
- if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0) {
- index = FXFT_Get_Char_Index(face, charcode);
- }
- if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN)) {
- return FXFT_Get_Char_Index(face, charcode);
- }
- }
- return charcode;
-}
-FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCodeEx(FX_DWORD charcode, int encoding)
-{
- FXFT_Face face = m_pFont->GetFace();
- if (!face) {
- return charcode;
- }
- if (encoding == ENCODING_UNICODE) {
- return GlyphFromCharCode(charcode);
- } else {
- int nmaps = FXFT_Get_Face_CharmapCount(m_pFont->m_Face);
- int i = 0;
- while (i < nmaps) {
- int encoding = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i++]);
- if (encoding != FXFT_ENCODING_UNICODE) {
- FXFT_Select_Charmap(face, encoding);
- break;
- }
- }
- }
- return FXFT_Get_Char_Index(face, charcode);
-}
-IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont)
-{
- CFX_UnicodeEncoding* pEncoding = NULL;
- pEncoding = FX_NEW CFX_UnicodeEncoding(pFont);
- return pEncoding;
-}
+// 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 "../../../include/fxge/fx_ge.h"
+#include "../../../include/fxge/fx_freetype.h"
+#include "text_int.h"
+#define EM_ADJUST(em, a) (em == 0?(a): (a)*1000/em)
+extern void _FPDFAPI_GetInternalFontData(int id1, FX_LPCBYTE& data, FX_DWORD& size);
+CFX_Font::CFX_Font()
+{
+ m_pSubstFont = NULL;
+ m_Face = NULL;
+ m_bEmbedded = FALSE;
+ m_bVertical = FALSE;
+ m_pFontData = NULL;
+ m_pFontDataAllocation = NULL;
+ m_dwSize = 0;
+ m_pOwnedStream = NULL;
+ m_pGsubData = NULL;
+ m_pPlatformFont = NULL;
+ m_pPlatformFontCollection = NULL;
+ m_pDwFont = NULL;
+ m_hHandle = NULL;
+ m_bDwLoaded = FALSE;
+}
+CFX_Font::~CFX_Font()
+{
+ if (m_pSubstFont) {
+ delete m_pSubstFont;
+ m_pSubstFont = NULL;
+ }
+#ifdef FOXIT_CHROME_BUILD
+ if (m_pFontDataAllocation) {
+ FX_Free(m_pFontDataAllocation);
+ m_pFontDataAllocation = NULL;
+ }
+#endif
+ if (m_Face) {
+#ifdef FOXIT_CHROME_BUILD
+ FXFT_Library library = FXFT_Get_Face_FreeType(m_Face);
+ if (FXFT_Get_Face_External_Stream(m_Face)) {
+ FXFT_Clear_Face_External_Stream(m_Face);
+ }
+#endif
+ if(m_bEmbedded) {
+ DeleteFace();
+ } else {
+ CFX_GEModule::Get()->GetFontMgr()->ReleaseFace(m_Face);
+ }
+ }
+ if (m_pOwnedStream) {
+ FX_Free(m_pOwnedStream);
+ m_pOwnedStream = NULL;
+ }
+ if (m_pGsubData) {
+ FX_Free(m_pGsubData);
+ m_pGsubData = NULL;
+ }
+#if (_FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && (!defined(_FPDFAPI_MINI_)))
+ ReleasePlatformResource();
+#endif
+}
+void CFX_Font::DeleteFace()
+{
+ FXFT_Done_Face(m_Face);
+ m_Face = NULL;
+}
+FX_BOOL CFX_Font::LoadSubst(const CFX_ByteString& face_name, FX_BOOL bTrueType, FX_DWORD flags,
+ int weight, int italic_angle, int CharsetCP, FX_BOOL bVertical)
+{
+ m_bEmbedded = FALSE;
+ m_bVertical = bVertical;
+ m_pSubstFont = FX_NEW CFX_SubstFont;
+ if (!m_pSubstFont) {
+ return FALSE;
+ }
+ m_Face = CFX_GEModule::Get()->GetFontMgr()->FindSubstFont(face_name, bTrueType, flags, weight, italic_angle,
+ CharsetCP, m_pSubstFont);
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if(m_pSubstFont->m_ExtHandle) {
+ m_pPlatformFont = m_pSubstFont->m_ExtHandle;
+ m_pSubstFont->m_ExtHandle = NULL;
+ }
+#endif
+ if (m_Face) {
+ m_pFontData = FXFT_Get_Face_Stream_Base(m_Face);
+ m_dwSize = FXFT_Get_Face_Stream_Size(m_Face);
+ }
+ return TRUE;
+}
+extern "C" {
+ unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset,
+ unsigned char* buffer, unsigned long count)
+ {
+ if (count == 0) {
+ return 0;
+ }
+ IFX_FileRead* pFile = (IFX_FileRead*)stream->descriptor.pointer;
+ int res = pFile->ReadBlock(buffer, offset, count);
+ if (res) {
+ return count;
+ }
+ return 0;
+ }
+ void _FTStreamClose(FXFT_Stream stream)
+ {
+ }
+};
+FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream)
+{
+ FXFT_Stream stream1 = (FXFT_Stream)FX_Alloc(FX_BYTE, sizeof (FXFT_StreamRec));
+ if (!stream1) {
+ return FALSE;
+ }
+ stream1->base = NULL;
+ stream1->size = (unsigned long)pFile->GetSize();
+ stream1->pos = 0;
+ stream1->descriptor.pointer = pFile;
+ stream1->close = _FTStreamClose;
+ stream1->read = _FTStreamRead;
+ FXFT_Open_Args args;
+ args.flags = FT_OPEN_STREAM;
+ args.stream = stream1;
+ if (FXFT_Open_Face(library, &args, 0, Face)) {
+ FX_Free(stream1);
+ return FALSE;
+ }
+ if (stream) {
+ *stream = stream1;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_Font::LoadFile(IFX_FileRead* pFile)
+{
+ m_bEmbedded = FALSE;
+ FXFT_Library library;
+ if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
+ FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
+ }
+ library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
+ FXFT_Stream stream = NULL;
+ if (!_LoadFile(library, &m_Face, pFile, &stream)) {
+ return FALSE;
+ }
+ m_pOwnedStream = stream;
+ FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
+ return TRUE;
+}
+int CFX_Font::GetGlyphWidth(FX_DWORD glyph_index)
+{
+ if (!m_Face) {
+ return 0;
+ }
+ if (m_pSubstFont && (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM)) {
+ AdjustMMParams(glyph_index, 0, 0);
+ }
+ int err = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
+ if (err) {
+ return 0;
+ }
+ int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Glyph_HoriAdvance(m_Face));
+ return width;
+}
+static FXFT_Face FT_LoadFont(FX_LPBYTE pData, int size)
+{
+ FXFT_Library library;
+ if (CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary == NULL) {
+ FXFT_Init_FreeType(&CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary);
+ }
+ library = CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary;
+ FXFT_Face face;
+ int error = FXFT_New_Memory_Face(library, pData, size, 0, &face);
+ if (error) {
+ return NULL;
+ }
+ error = FXFT_Set_Pixel_Sizes(face, 64, 64);
+ if (error) {
+ return NULL;
+ }
+ return face;
+}
+FX_BOOL CFX_Font::LoadEmbedded(FX_LPCBYTE data, FX_DWORD size)
+{
+#ifdef FOXIT_CHROME_BUILD
+ m_pFontDataAllocation = FX_Alloc(FX_BYTE, size);
+ if (!m_pFontDataAllocation) {
+ return FALSE;
+ }
+ FXSYS_memcpy32(m_pFontDataAllocation, data, size);
+ m_Face = FT_LoadFont((FX_LPBYTE)m_pFontDataAllocation, size);
+ m_pFontData = (FX_LPBYTE)m_pFontDataAllocation;
+#else
+ m_Face = FT_LoadFont((FX_LPBYTE)data, size);
+ m_pFontData = (FX_LPBYTE)data;
+#endif
+ m_bEmbedded = TRUE;
+ m_dwSize = size;
+ return m_Face != NULL;
+}
+FX_BOOL CFX_Font::IsTTFont()
+{
+ if (m_Face == NULL) {
+ return FALSE;
+ }
+ return FXFT_Is_Face_TT_OT(m_Face) == FXFT_FACE_FLAG_SFNT;
+}
+int CFX_Font::GetAscent() const
+{
+ if (m_Face == NULL) {
+ return 0;
+ }
+ int ascent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Ascender(m_Face));
+ return ascent;
+}
+int CFX_Font::GetDescent() const
+{
+ if (m_Face == NULL) {
+ return 0;
+ }
+ int descent = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Descender(m_Face));
+ return descent;
+}
+FX_BOOL CFX_Font::GetGlyphBBox(FX_DWORD glyph_index, FX_RECT &bbox)
+{
+ if (m_Face == NULL) {
+ return FALSE;
+ }
+ if (FXFT_Is_Face_Tricky(m_Face)) {
+ int error = FXFT_Set_Char_Size(m_Face, 0, 1000 * 64, 72, 72);
+ if (error) {
+ return FALSE;
+ }
+ error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
+ if (error) {
+ return FALSE;
+ }
+ FXFT_BBox cbox;
+ FT_Glyph glyph;
+ error = FXFT_Get_Glyph(((FXFT_Face)m_Face)->glyph, &glyph);
+ if (error) {
+ return FALSE;
+ }
+ FXFT_Glyph_Get_CBox(glyph, FXFT_GLYPH_BBOX_PIXELS, &cbox);
+ int pixel_size_x = ((FXFT_Face)m_Face)->size->metrics.x_ppem,
+ pixel_size_y = ((FXFT_Face)m_Face)->size->metrics.y_ppem;
+ if (pixel_size_x == 0 || pixel_size_y == 0) {
+ bbox.left = cbox.xMin;
+ bbox.right = cbox.xMax;
+ bbox.top = cbox.yMax;
+ bbox.bottom = cbox.yMin;
+ } else {
+ bbox.left = cbox.xMin * 1000 / pixel_size_x;
+ bbox.right = cbox.xMax * 1000 / pixel_size_x;
+ bbox.top = cbox.yMax * 1000 / pixel_size_y;
+ bbox.bottom = cbox.yMin * 1000 / pixel_size_y;
+ }
+ if (bbox.top > FXFT_Get_Face_Ascender(m_Face)) {
+ bbox.top = FXFT_Get_Face_Ascender(m_Face);
+ }
+ if (bbox.bottom < FXFT_Get_Face_Descender(m_Face)) {
+ bbox.bottom = FXFT_Get_Face_Descender(m_Face);
+ }
+ FT_Done_Glyph(glyph);
+ return FXFT_Set_Pixel_Sizes(m_Face, 0, 64) == 0;
+ }
+ if (FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH)) {
+ return FALSE;
+ }
+ int em = FXFT_Get_Face_UnitsPerEM(m_Face);
+ if (em == 0) {
+ bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face);
+ bbox.bottom = FXFT_Get_Glyph_HoriBearingY(m_Face);
+ bbox.top = bbox.bottom - FXFT_Get_Glyph_Height(m_Face);
+ bbox.right = bbox.left + FXFT_Get_Glyph_Width(m_Face);
+ } else {
+ bbox.left = FXFT_Get_Glyph_HoriBearingX(m_Face) * 1000 / em;
+ bbox.top = (FXFT_Get_Glyph_HoriBearingY(m_Face) - FXFT_Get_Glyph_Height(m_Face)) * 1000 / em;
+ bbox.right = (FXFT_Get_Glyph_HoriBearingX(m_Face) + FXFT_Get_Glyph_Width(m_Face)) * 1000 / em;
+ bbox.bottom = (FXFT_Get_Glyph_HoriBearingY(m_Face)) * 1000 / em;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_Font::IsItalic()
+{
+ if (m_Face == NULL) {
+ return FALSE;
+ }
+ FX_BOOL ret = FXFT_Is_Face_Italic(m_Face) == FXFT_STYLE_FLAG_ITALIC;
+ if (!ret) {
+ CFX_ByteString str(FXFT_Get_Face_Style_Name(m_Face));
+ str.MakeLower();
+ if (str.Find("italic") != -1) {
+ ret = TRUE;
+ }
+ }
+ return ret;
+}
+FX_BOOL CFX_Font::IsBold()
+{
+ if (m_Face == NULL) {
+ return FALSE;
+ }
+ return FXFT_Is_Face_Bold(m_Face) == FXFT_STYLE_FLAG_BOLD;
+}
+FX_BOOL CFX_Font::IsFixedWidth()
+{
+ if (m_Face == NULL) {
+ return FALSE;
+ }
+ return FXFT_Is_Face_fixedwidth(m_Face);
+}
+CFX_WideString CFX_Font::GetPsName() const
+{
+ if (m_Face == NULL) {
+ return CFX_WideString();
+ }
+ CFX_WideString psName = CFX_WideString::FromLocal(FXFT_Get_Postscript_Name(m_Face));
+ if (psName.IsEmpty()) {
+ psName = CFX_WideString::FromLocal("Untitled");
+ }
+ return psName;
+}
+CFX_ByteString CFX_Font::GetFamilyName() const
+{
+ if (m_Face == NULL && m_pSubstFont == NULL) {
+ return CFX_ByteString();
+ }
+ if (m_Face) {
+ return CFX_ByteString(FXFT_Get_Face_Family_Name(m_Face));
+ } else {
+ return m_pSubstFont->m_Family;
+ }
+}
+CFX_ByteString CFX_Font::GetFaceName() const
+{
+ if (m_Face == NULL && m_pSubstFont == NULL) {
+ return CFX_ByteString();
+ }
+ if (m_Face) {
+ CFX_ByteString facename;
+ CFX_ByteString style = CFX_ByteString(FXFT_Get_Face_Style_Name(m_Face));
+ facename = GetFamilyName();
+ if (facename.IsEmpty()) {
+ facename = "Untitled";
+ }
+ if (!style.IsEmpty() && style != "Regular") {
+ facename += " " + style;
+ }
+ return facename;
+ } else {
+ return m_pSubstFont->m_Family;
+ }
+}
+FX_BOOL CFX_Font::GetBBox(FX_RECT &bbox)
+{
+ if (m_Face == NULL) {
+ return FALSE;
+ }
+ int em = FXFT_Get_Face_UnitsPerEM(m_Face);
+ if (em == 0) {
+ bbox.left = FXFT_Get_Face_xMin(m_Face);
+ bbox.bottom = FXFT_Get_Face_yMax(m_Face);
+ bbox.top = FXFT_Get_Face_yMin(m_Face);
+ bbox.right = FXFT_Get_Face_xMax(m_Face);
+ } else {
+ bbox.left = FXFT_Get_Face_xMin(m_Face) * 1000 / em;
+ bbox.top = FXFT_Get_Face_yMin(m_Face) * 1000 / em;
+ bbox.right = FXFT_Get_Face_xMax(m_Face) * 1000 / em;
+ bbox.bottom = FXFT_Get_Face_yMax(m_Face) * 1000 / em;
+ }
+ return TRUE;
+}
+int CFX_Font::GetHeight()
+{
+ if (m_Face == NULL) {
+ return 0;
+ }
+ int height = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_Height(m_Face));
+ return height;
+}
+int CFX_Font::GetMaxAdvanceWidth()
+{
+ if (m_Face == NULL) {
+ return 0;
+ }
+ int width = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_MaxAdvanceWidth(m_Face));
+ return width;
+}
+int CFX_Font::GetULPos()
+{
+ if (m_Face == NULL) {
+ return 0;
+ }
+ int pos = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_UnderLinePosition(m_Face));
+ return pos;
+}
+int CFX_Font::GetULthickness()
+{
+ if (m_Face == NULL) {
+ return 0;
+ }
+ int thickness = EM_ADJUST(FXFT_Get_Face_UnitsPerEM(m_Face), FXFT_Get_Face_UnderLineThickness(m_Face));
+ return thickness;
+}
+CFX_UnicodeEncoding::CFX_UnicodeEncoding(CFX_Font* pFont)
+{
+ m_pFont = pFont;
+}
+FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCode(FX_DWORD charcode)
+{
+ FXFT_Face face = m_pFont->GetFace();
+ if (!face) {
+ return charcode;
+ }
+ if (FXFT_Select_Charmap(face, FXFT_ENCODING_UNICODE) == 0) {
+ return FXFT_Get_Char_Index(face, charcode);
+ }
+ if (m_pFont->m_pSubstFont && m_pFont->m_pSubstFont->m_Charset == 2) {
+ FX_DWORD index = 0;
+ if (FXFT_Select_Charmap(face, FXFT_ENCODING_MS_SYMBOL) == 0) {
+ index = FXFT_Get_Char_Index(face, charcode);
+ }
+ if (!index && !FXFT_Select_Charmap(face, FXFT_ENCODING_APPLE_ROMAN)) {
+ return FXFT_Get_Char_Index(face, charcode);
+ }
+ }
+ return charcode;
+}
+FX_DWORD CFX_UnicodeEncoding::GlyphFromCharCodeEx(FX_DWORD charcode, int encoding)
+{
+ FXFT_Face face = m_pFont->GetFace();
+ if (!face) {
+ return charcode;
+ }
+ if (encoding == ENCODING_UNICODE) {
+ return GlyphFromCharCode(charcode);
+ } else {
+ int nmaps = FXFT_Get_Face_CharmapCount(m_pFont->m_Face);
+ int i = 0;
+ while (i < nmaps) {
+ int encoding = FXFT_Get_Charmap_Encoding(FXFT_Get_Face_Charmaps(face)[i++]);
+ if (encoding != FXFT_ENCODING_UNICODE) {
+ FXFT_Select_Charmap(face, encoding);
+ break;
+ }
+ }
+ }
+ return FXFT_Get_Char_Index(face, charcode);
+}
+IFX_FontEncoding* FXGE_CreateUnicodeEncoding(CFX_Font* pFont)
+{
+ CFX_UnicodeEncoding* pEncoding = NULL;
+ pEncoding = FX_NEW CFX_UnicodeEncoding(pFont);
+ return pEncoding;
+}
diff --git a/core/src/fxge/ge/fx_ge_fontmap.cpp b/core/src/fxge/ge/fx_ge_fontmap.cpp
index 6549e8e531..8c2751d84a 100644
--- a/core/src/fxge/ge/fx_ge_fontmap.cpp
+++ b/core/src/fxge/ge/fx_ge_fontmap.cpp
@@ -1,1558 +1,1558 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#include "../../../include/fxge/fx_freetype.h"
-#include "text_int.h"
-#define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1])
-#define GET_TT_LONG(w) (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3])
-CFX_SubstFont::CFX_SubstFont()
-{
- m_ExtHandle = NULL;
- m_Charset = 0;
- m_SubstFlags = 0;
- m_Weight = 0;
- m_ItalicAngle = 0;
- m_bSubstOfCJK = FALSE;
- m_WeightCJK = 0;
- m_bItlicCJK = FALSE;
-}
-CTTFontDesc::~CTTFontDesc()
-{
- if (m_Type == 1) {
- if (m_SingleFace.m_pFace) {
- FXFT_Done_Face(m_SingleFace.m_pFace);
- }
- } else if (m_Type == 2) {
- for (int i = 0; i < 16; i ++)
- if (m_TTCFace.m_pFaces[i]) {
- FXFT_Done_Face(m_TTCFace.m_pFaces[i]);
- }
- }
- if (m_pFontData) {
- FX_Free(m_pFontData);
- }
-}
-FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face)
-{
- if (m_Type == 1) {
- if (m_SingleFace.m_pFace != face) {
- return FALSE;
- }
- } else if (m_Type == 2) {
- int i;
- for (i = 0; i < 16; i ++)
- if (m_TTCFace.m_pFaces[i] == face) {
- break;
- }
- if (i == 16) {
- return FALSE;
- }
- }
- m_RefCount --;
- if (m_RefCount) {
- return FALSE;
- }
- delete this;
- return TRUE;
-}
-CFX_FontMgr::CFX_FontMgr()
-{
- m_pBuiltinMapper = FX_NEW CFX_FontMapper;
- if (!m_pBuiltinMapper) {
- return;
- }
- m_pBuiltinMapper->m_pFontMgr = this;
- m_pExtMapper = NULL;
- m_FTLibrary = NULL;
- FXSYS_memset32(m_ExternalFonts, 0, sizeof m_ExternalFonts);
-}
-CFX_FontMgr::~CFX_FontMgr()
-{
- if (m_pBuiltinMapper) {
- delete m_pBuiltinMapper;
- }
- FreeCache();
- if (m_FTLibrary) {
- FXFT_Done_FreeType(m_FTLibrary);
- }
-}
-void CFX_FontMgr::InitFTLibrary()
-{
- if (m_FTLibrary == NULL) {
- FXFT_Init_FreeType(&m_FTLibrary);
- }
-}
-void CFX_FontMgr::FreeCache()
-{
- FX_POSITION pos = m_FaceMap.GetStartPosition();
- while(pos) {
- CFX_ByteString Key;
- CTTFontDesc* face;
- m_FaceMap.GetNextAssoc(pos, Key, (void*&)face);
- delete face;
- }
- m_FaceMap.RemoveAll();
-}
-void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo)
-{
- m_pBuiltinMapper->SetSystemFontInfo(pFontInfo);
-}
-FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bTrueType,
- FX_DWORD flags, int weight, int italic_angle, int CharsetCP, CFX_SubstFont* pSubstFont)
-{
- if (m_FTLibrary == NULL) {
- FXFT_Init_FreeType(&m_FTLibrary);
- }
- if (m_pExtMapper) {
- FXFT_Face face = m_pExtMapper->FindSubstFont(face_name, bTrueType, flags, weight, italic_angle,
- CharsetCP, pSubstFont);
- if (face) {
- return face;
- }
- }
- return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight, italic_angle,
- CharsetCP, pSubstFont);
-}
-FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name,
- int weight, FX_BOOL bItalic, FX_LPBYTE& pFontData)
-{
- CFX_ByteString key(face_name);
- key += ',';
- key += CFX_ByteString::FormatInteger(weight);
- key += bItalic ? 'I' : 'N';
- CTTFontDesc* pFontDesc = NULL;
- m_FaceMap.Lookup(key, (void*&)pFontDesc);
- if(pFontDesc) {
- pFontData = pFontDesc->m_pFontData;
- pFontDesc->m_RefCount ++;
- return pFontDesc->m_SingleFace.m_pFace;
- }
- return NULL;
-}
-FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name,
- int weight, FX_BOOL bItalic, FX_LPBYTE pData, FX_DWORD size, int face_index)
-{
- CTTFontDesc* pFontDesc = FX_NEW CTTFontDesc;
- if (!pFontDesc) {
- return NULL;
- }
- pFontDesc->m_Type = 1;
- pFontDesc->m_SingleFace.m_pFace = NULL;
- pFontDesc->m_SingleFace.m_bBold = weight;
- pFontDesc->m_SingleFace.m_bItalic = bItalic;
- pFontDesc->m_pFontData = pData;
- pFontDesc->m_RefCount = 1;
- FXFT_Library library;
- if (m_FTLibrary == NULL) {
- FXFT_Init_FreeType(&m_FTLibrary);
- }
- library = m_FTLibrary;
- int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &pFontDesc->m_SingleFace.m_pFace);
- if (ret) {
- delete pFontDesc;
- return NULL;
- }
- ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace.m_pFace, 64, 64);
- if (ret) {
- delete pFontDesc;
- return NULL;
- }
- CFX_ByteString key(face_name);
- key += ',';
- key += CFX_ByteString::FormatInteger(weight);
- key += bItalic ? 'I' : 'N';
- m_FaceMap.SetAt(key, pFontDesc);
- return pFontDesc->m_SingleFace.m_pFace;
-}
-const FX_LPCSTR g_Base14FontNames[14] = {
- "Courier",
- "Courier-Bold",
- "Courier-BoldOblique",
- "Courier-Oblique",
- "Helvetica",
- "Helvetica-Bold",
- "Helvetica-BoldOblique",
- "Helvetica-Oblique",
- "Times-Roman",
- "Times-Bold",
- "Times-BoldItalic",
- "Times-Italic",
- "Symbol",
- "ZapfDingbats",
-};
-const struct _AltFontName {
- const FX_CHAR* m_pName;
- int m_Index;
-}
-g_AltFontNames[] = {
- {"Arial", 4},
- {"Arial,Bold", 5},
- {"Arial,BoldItalic", 6},
- {"Arial,Italic", 7},
- {"Arial-Bold", 5},
- {"Arial-BoldItalic", 6},
- {"Arial-BoldItalicMT", 6},
- {"Arial-BoldMT", 5},
- {"Arial-Italic", 7},
- {"Arial-ItalicMT", 7},
- {"ArialBold", 5},
- {"ArialBoldItalic", 6},
- {"ArialItalic", 7},
- {"ArialMT", 4},
- {"ArialMT,Bold", 5},
- {"ArialMT,BoldItalic", 6},
- {"ArialMT,Italic", 7},
- {"ArialRoundedMTBold", 5},
- {"Courier", 0},
- {"Courier,Bold", 1},
- {"Courier,BoldItalic", 2},
- {"Courier,Italic", 3},
- {"Courier-Bold", 1},
- {"Courier-BoldOblique", 2},
- {"Courier-Oblique", 3},
- {"CourierBold", 1},
- {"CourierBoldItalic", 2},
- {"CourierItalic", 3},
- {"CourierNew", 0},
- {"CourierNew,Bold", 1},
- {"CourierNew,BoldItalic", 2},
- {"CourierNew,Italic", 3},
- {"CourierNew-Bold", 1},
- {"CourierNew-BoldItalic", 2},
- {"CourierNew-Italic", 3},
- {"CourierNewBold", 1},
- {"CourierNewBoldItalic", 2},
- {"CourierNewItalic", 3},
- {"CourierNewPS-BoldItalicMT", 2},
- {"CourierNewPS-BoldMT", 1},
- {"CourierNewPS-ItalicMT", 3},
- {"CourierNewPSMT", 0},
- {"CourierStd", 0},
- {"CourierStd-Bold", 1},
- {"CourierStd-BoldOblique", 2},
- {"CourierStd-Oblique", 3},
- {"Helvetica", 4},
- {"Helvetica,Bold", 5},
- {"Helvetica,BoldItalic", 6},
- {"Helvetica,Italic", 7},
- {"Helvetica-Bold", 5},
- {"Helvetica-BoldItalic", 6},
- {"Helvetica-BoldOblique", 6},
- {"Helvetica-Italic", 7},
- {"Helvetica-Oblique", 7},
- {"HelveticaBold", 5},
- {"HelveticaBoldItalic", 6},
- {"HelveticaItalic", 7},
- {"Symbol", 12},
- {"SymbolMT", 12},
- {"Times-Bold", 9},
- {"Times-BoldItalic", 10},
- {"Times-Italic", 11},
- {"Times-Roman", 8},
- {"TimesBold", 9},
- {"TimesBoldItalic", 10},
- {"TimesItalic", 11},
- {"TimesNewRoman", 8},
- {"TimesNewRoman,Bold", 9},
- {"TimesNewRoman,BoldItalic", 10},
- {"TimesNewRoman,Italic", 11},
- {"TimesNewRoman-Bold", 9},
- {"TimesNewRoman-BoldItalic", 10},
- {"TimesNewRoman-Italic", 11},
- {"TimesNewRomanBold", 9},
- {"TimesNewRomanBoldItalic", 10},
- {"TimesNewRomanItalic", 11},
- {"TimesNewRomanPS", 8},
- {"TimesNewRomanPS-Bold", 9},
- {"TimesNewRomanPS-BoldItalic", 10},
- {"TimesNewRomanPS-BoldItalicMT", 10},
- {"TimesNewRomanPS-BoldMT", 9},
- {"TimesNewRomanPS-Italic", 11},
- {"TimesNewRomanPS-ItalicMT", 11},
- {"TimesNewRomanPSMT", 8},
- {"TimesNewRomanPSMT,Bold", 9},
- {"TimesNewRomanPSMT,BoldItalic", 10},
- {"TimesNewRomanPSMT,Italic", 11},
- {"ZapfDingbats", 13},
-};
-extern "C" {
- static int compareString(const void* key, const void* element)
- {
- return FXSYS_stricmp((FX_LPCSTR)key, ((_AltFontName*)element)->m_pName);
- }
-}
-int _PDF_GetStandardFontName(CFX_ByteString& name)
-{
- _AltFontName* found = (_AltFontName*)FXSYS_bsearch((FX_LPCSTR)name, g_AltFontNames,
- sizeof g_AltFontNames / sizeof (_AltFontName), sizeof (_AltFontName), compareString);
- if (found == NULL) {
- return -1;
- }
- name = g_Base14FontNames[found->m_Index];
- return found->m_Index;
-}
-int GetTTCIndex(FX_LPCBYTE pFontData, FX_DWORD ttc_size, FX_DWORD font_offset)
-{
- int face_index = 0;
- FX_LPCBYTE p = pFontData + 8;
- FX_DWORD nfont = GET_TT_LONG(p);
- FX_DWORD index;
- for (index = 0; index < nfont; index ++) {
- p = pFontData + 12 + index * 4;
- if (GET_TT_LONG(p) == font_offset) {
- break;
- }
- }
- if(index >= nfont) {
- face_index = 0;
- } else {
- face_index = index;
- }
- return face_index;
-}
-FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size, FX_DWORD checksum,
- int font_offset, FX_LPBYTE& pFontData)
-{
- CFX_ByteString key;
- key.Format("%d:%d", ttc_size, checksum);
- CTTFontDesc* pFontDesc = NULL;
- m_FaceMap.Lookup(key, (void*&)pFontDesc);
- if (pFontDesc == NULL) {
- return NULL;
- }
- pFontData = pFontDesc->m_pFontData;
- pFontDesc->m_RefCount ++;
- int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
- if (pFontDesc->m_TTCFace.m_pFaces[face_index] == NULL) {
- pFontDesc->m_TTCFace.m_pFaces[face_index] = GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
- }
- return pFontDesc->m_TTCFace.m_pFaces[face_index];
-}
-FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size, FX_DWORD checksum,
- FX_LPBYTE pData, FX_DWORD size, int font_offset)
-{
- CFX_ByteString key;
- key.Format("%d:%d", ttc_size, checksum);
- CTTFontDesc* pFontDesc = FX_NEW CTTFontDesc;
- if (!pFontDesc) {
- return NULL;
- }
- pFontDesc->m_Type = 2;
- pFontDesc->m_pFontData = pData;
- for (int i = 0; i < 16; i ++) {
- pFontDesc->m_TTCFace.m_pFaces[i] = NULL;
- }
- pFontDesc->m_RefCount ++;
- key.Format("%d:%d", ttc_size, checksum);
- m_FaceMap.SetAt(key, pFontDesc);
- int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
- pFontDesc->m_TTCFace.m_pFaces[face_index] = GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
- return pFontDesc->m_TTCFace.m_pFaces[face_index];
-}
-FXFT_Face CFX_FontMgr::GetFixedFace(FX_LPCBYTE pData, FX_DWORD size, int face_index)
-{
- FXFT_Library library;
- if (m_FTLibrary == NULL) {
- FXFT_Init_FreeType(&m_FTLibrary);
- }
- library = m_FTLibrary;
- FXFT_Face face = NULL;
- int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &face);
- if (ret) {
- return NULL;
- }
- ret = FXFT_Set_Pixel_Sizes(face, 64, 64);
- if (ret) {
- return NULL;
- }
- return face;
-}
-FXFT_Face CFX_FontMgr::GetFileFace(FX_LPCSTR filename, int face_index)
-{
- FXFT_Library library;
- if (m_FTLibrary == NULL) {
- FXFT_Init_FreeType(&m_FTLibrary);
- }
- library = m_FTLibrary;
- FXFT_Face face = NULL;
- int ret = FXFT_New_Face(library, filename, face_index, &face);
- if (ret) {
- return NULL;
- }
- ret = FXFT_Set_Pixel_Sizes(face, 64, 64);
- if (ret) {
- return NULL;
- }
- return face;
-}
-void CFX_FontMgr::ReleaseFace(FXFT_Face face)
-{
- if (face == NULL) {
- return;
- }
- FX_POSITION pos = m_FaceMap.GetStartPosition();
- while(pos) {
- CFX_ByteString Key;
- CTTFontDesc* ttface;
- m_FaceMap.GetNextAssoc(pos, Key, (void*&)ttface);
- if (ttface->ReleaseFace(face)) {
- m_FaceMap.RemoveKey(Key);
- }
- }
-}
-extern "C" {
- extern const unsigned char g_FoxitFixedItalicFontData [18746];
- extern const unsigned char g_FoxitFixedFontData [17597];
- extern const unsigned char g_FoxitSansItalicFontData [16339];
- extern const unsigned char g_FoxitSansFontData [15025];
- extern const unsigned char g_FoxitSerifItalicFontData [21227];
- extern const unsigned char g_FoxitSerifFontData [19469];
- extern const unsigned char g_FoxitFixedBoldItalicFontData [19151];
- extern const unsigned char g_FoxitFixedBoldFontData [18055];
- extern const unsigned char g_FoxitSansBoldItalicFontData [16418];
- extern const unsigned char g_FoxitSansBoldFontData [16344];
- extern const unsigned char g_FoxitSerifBoldItalicFontData [20733];
- extern const unsigned char g_FoxitSerifBoldFontData [19395];
- extern const unsigned char g_FoxitSymbolFontData[16729];
- extern const unsigned char g_FoxitDingbatsFontData[29513];
- extern const unsigned char g_FoxitSerifMMFontData[113417];
- extern const unsigned char g_FoxitSansMMFontData[66919];
-};
-const FoxitFonts g_FoxitFonts[14] = {
- {g_FoxitFixedFontData, 17597},
- {g_FoxitFixedBoldFontData, 18055},
- {g_FoxitFixedBoldItalicFontData, 19151},
- {g_FoxitFixedItalicFontData, 18746},
- {g_FoxitSansFontData, 15025},
- {g_FoxitSansBoldFontData, 16344},
- {g_FoxitSansBoldItalicFontData, 16418},
- {g_FoxitSansItalicFontData, 16339},
- {g_FoxitSerifFontData, 19469},
- {g_FoxitSerifBoldFontData, 19395},
- {g_FoxitSerifBoldItalicFontData, 20733},
- {g_FoxitSerifItalicFontData, 21227},
- {g_FoxitSymbolFontData, 16729},
- {g_FoxitDingbatsFontData, 29513},
-};
-void _FPDFAPI_GetInternalFontData(int id, FX_LPCBYTE& data, FX_DWORD& size)
-{
- CFX_GEModule::Get()->GetFontMgr()->GetStandardFont(data, size, id);
-}
-FX_BOOL CFX_FontMgr::GetStandardFont(FX_LPCBYTE& pFontData, FX_DWORD& size, int index)
-{
- if (index > 15 || index < 0) {
- return FALSE;
- }
- {
- if (index >= 14) {
- if (index == 14) {
- pFontData = g_FoxitSerifMMFontData;
- size = 113417;
- } else {
- pFontData = g_FoxitSansMMFontData;
- size = 66919;
- }
- } else {
- pFontData = g_FoxitFonts[index].m_pFontData;
- size = g_FoxitFonts[index].m_dwSize;
- }
- }
- return TRUE;
-}
-CFX_FontMapper::CFX_FontMapper()
-{
- FXSYS_memset32(m_FoxitFaces, 0, sizeof m_FoxitFaces);
- m_MMFaces[0] = m_MMFaces[1] = NULL;
- m_pFontInfo = NULL;
- m_bListLoaded = FALSE;
- m_pFontEnumerator = NULL;
-}
-CFX_FontMapper::~CFX_FontMapper()
-{
- for (int i = 0; i < 14; i ++)
- if (m_FoxitFaces[i]) {
- FXFT_Done_Face(m_FoxitFaces[i]);
- }
- if (m_MMFaces[0]) {
- FXFT_Done_Face(m_MMFaces[0]);
- }
- if (m_MMFaces[1]) {
- FXFT_Done_Face(m_MMFaces[1]);
- }
- if (m_pFontInfo) {
- m_pFontInfo->Release();
- }
-}
-void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo)
-{
- if (pFontInfo == NULL) {
- return;
- }
- if (m_pFontInfo) {
- m_pFontInfo->Release();
- }
- m_pFontInfo = pFontInfo;
-}
-static CFX_ByteString _TT_NormalizeName(FX_LPCSTR family)
-{
- CFX_ByteString norm(family, -1);
- norm.Remove(' ');
- norm.Remove('-');
- norm.Remove(',');
- int pos = norm.Find('+');
- if (pos > 0) {
- norm = norm.Left(pos);
- }
- norm.MakeLower();
- return norm;
-}
-CFX_ByteString _FPDF_GetNameFromTT(FX_LPCBYTE name_table, FX_DWORD name_id)
-{
- FX_LPCBYTE ptr = name_table + 2;
- int name_count = GET_TT_SHORT(ptr);
- int string_offset = GET_TT_SHORT(ptr + 2);
- FX_LPCBYTE string_ptr = name_table + string_offset;
- ptr += 4;
- for (int i = 0; i < name_count; i ++) {
- if (GET_TT_SHORT(ptr + 6) == name_id && GET_TT_SHORT(ptr) == 1 && GET_TT_SHORT(ptr + 2) == 0) {
- return CFX_ByteStringC(string_ptr + GET_TT_SHORT(ptr + 10), GET_TT_SHORT(ptr + 8));
- }
- ptr += 12;
- }
- return CFX_ByteString();
-}
-static CFX_ByteString _FPDF_ReadStringFromFile(FXSYS_FILE* pFile, FX_DWORD size)
-{
- CFX_ByteString buffer;
- if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile)) {
- return CFX_ByteString();
- }
- buffer.ReleaseBuffer(size);
- return buffer;
-}
-static CFX_ByteString _FPDF_ReadStringFromStreamFile(IFX_FileStream* pFile, FX_DWORD size)
-{
- CFX_ByteString buffer;
- if (!pFile->ReadBlock(buffer.GetBuffer(size), size)) {
- return CFX_ByteString();
- }
- buffer.ReleaseBuffer(size);
- return buffer;
-}
-CFX_ByteString _FPDF_LoadTableFromTT(FXSYS_FILE* pFile, FX_LPCBYTE pTables, FX_DWORD nTables, FX_DWORD tag)
-{
- for (FX_DWORD i = 0; i < nTables; i ++) {
- FX_LPCBYTE p = pTables + i * 16;
- if (GET_TT_LONG(p) == tag) {
- FX_DWORD offset = GET_TT_LONG(p + 8);
- FX_DWORD size = GET_TT_LONG(p + 12);
- FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
- return _FPDF_ReadStringFromFile(pFile, size);
- }
- }
- return CFX_ByteString();
-}
-CFX_ByteString _FPDF_LoadTableFromTTStreamFile(IFX_FileStream* pFile, FX_LPCBYTE pTables, FX_DWORD nTables, FX_DWORD tag)
-{
- for (FX_DWORD i = 0; i < nTables; i ++) {
- FX_LPCBYTE p = pTables + i * 16;
- if (GET_TT_LONG(p) == tag) {
- FX_DWORD offset = GET_TT_LONG(p + 8);
- FX_DWORD size = GET_TT_LONG(p + 12);
- CFX_ByteString buffer;
- if (!pFile->ReadBlock(buffer.GetBuffer(size), offset, size)) {
- return CFX_ByteString();
- }
- buffer.ReleaseBuffer(size);
- return buffer;
- }
- }
- return CFX_ByteString();
-}
-CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont)
-{
- if (m_pFontInfo == NULL) {
- CFX_ByteString();
- }
- CFX_ByteString result;
- FX_DWORD size = m_pFontInfo->GetFontData(hFont, 0x6e616d65, NULL, 0);
- if (size) {
- FX_LPBYTE buffer = FX_Alloc(FX_BYTE, size);
- if (!buffer) {
- return result;
- }
- m_pFontInfo->GetFontData(hFont, 0x6e616d65, buffer, size);
- result = _FPDF_GetNameFromTT(buffer, 6);
- FX_Free(buffer);
- }
- return result;
-}
-void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset)
-{
- if (m_pFontInfo == NULL) {
- return;
- }
- if (m_CharsetArray.Find((FX_DWORD)charset) == -1) {
- m_CharsetArray.Add((FX_DWORD)charset);
- m_FaceArray.Add(name);
- }
- if (name == m_LastFamily) {
- return;
- }
- FX_LPCBYTE ptr = name;
- FX_BOOL bLocalized = FALSE;
- for (int i = 0; i < name.GetLength(); i ++)
- if (ptr[i] > 0x80) {
- bLocalized = TRUE;
- break;
- }
- if (bLocalized) {
- void* hFont = m_pFontInfo->GetFont(name);
- if (hFont == NULL) {
- FX_BOOL bExact;
- hFont = m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, name, bExact);
- if (hFont == NULL) {
- return;
- }
- }
- CFX_ByteString new_name = GetPSNameFromTT(hFont);
- if (!new_name.IsEmpty()) {
- new_name.Insert(0, ' ');
- m_InstalledTTFonts.Add(new_name);
- }
- m_pFontInfo->DeleteFont(hFont);
- }
- m_InstalledTTFonts.Add(name);
- m_LastFamily = name;
-}
-void CFX_FontMapper::LoadInstalledFonts()
-{
- if (m_pFontInfo == NULL) {
- return;
- }
- if (m_bListLoaded) {
- return;
- }
- if (m_bListLoaded) {
- return;
- }
- m_pFontInfo->EnumFontList(this);
- m_bListLoaded = TRUE;
-}
-CFX_ByteString CFX_FontMapper::MatchInstalledFonts(const CFX_ByteString& norm_name)
-{
- LoadInstalledFonts();
- int i;
- for (i = m_InstalledTTFonts.GetSize() - 1; i >= 0; i --) {
- CFX_ByteString norm1 = _TT_NormalizeName(m_InstalledTTFonts[i]);
- if (norm1 == norm_name) {
- break;
- }
- }
- if (i < 0) {
- return CFX_ByteString();
- }
- CFX_ByteString match = m_InstalledTTFonts[i];
- if (match[0] == ' ') {
- match = m_InstalledTTFonts[i + 1];
- }
- return match;
-}
-typedef struct _CHARSET_MAP_ {
- FX_BYTE charset;
- FX_WORD codepage;
-} CHARSET_MAP;
-static const CHARSET_MAP g_Codepage2CharsetTable[] = {
- { 1 , 0 },
- { 2 , 42 },
- { 254, 437 },
- { 255, 850 },
- { 222, 874 },
- { 128, 932 },
- { 134, 936 },
- { 129, 949 },
- { 136, 950 },
- { 238, 1250 },
- { 204, 1251 },
- { 0, 1252 },
- { 161, 1253 },
- { 162, 1254 },
- { 177, 1255 },
- { 178, 1256 },
- { 186, 1257 },
- { 163, 1258 },
- { 130, 1361 },
- { 77, 10000 },
- { 78, 10001 },
- { 79, 10003 },
- { 80, 10008 },
- { 81, 10002 },
- { 83, 10005 },
- { 84, 10004 },
- { 85, 10006 },
- { 86, 10081 },
- { 87, 10021 },
- { 88, 10029 },
- { 89, 10007 },
-};
-FX_BYTE _GetCharsetFromCodePage(FX_WORD codepage)
-{
- FX_INT32 iEnd = sizeof(g_Codepage2CharsetTable) / sizeof(CHARSET_MAP) - 1;
- FXSYS_assert(iEnd >= 0);
- FX_INT32 iStart = 0, iMid;
- do {
- iMid = (iStart + iEnd) / 2;
- const CHARSET_MAP & cp = g_Codepage2CharsetTable[iMid];
- if (codepage == cp.codepage) {
- return cp.charset;
- } else if (codepage < cp.codepage) {
- iEnd = iMid - 1;
- } else {
- iStart = iMid + 1;
- }
- } while (iStart <= iEnd);
- return 1;
-}
-FX_DWORD _GetCodePageRangeFromCharset(int charset)
-{
- if (charset == FXFONT_EASTEUROPE_CHARSET) {
- return 1 << 1;
- }
- if (charset == FXFONT_GREEK_CHARSET) {
- return 1 << 3;
- }
- if (charset == FXFONT_TURKISH_CHARSET) {
- return 1 << 4;
- }
- if (charset == FXFONT_HEBREW_CHARSET) {
- return 1 << 5;
- }
- if (charset == FXFONT_ARABIC_CHARSET) {
- return 1 << 6;
- }
- if (charset == FXFONT_BALTIC_CHARSET) {
- return 1 << 7;
- }
- if (charset == FXFONT_THAI_CHARSET) {
- return 1 << 16;
- }
- if (charset == FXFONT_SHIFTJIS_CHARSET) {
- return 1 << 17;
- }
- if (charset == FXFONT_GB2312_CHARSET) {
- return 1 << 18;
- }
- if (charset == FXFONT_CHINESEBIG5_CHARSET) {
- return 1 << 20;
- }
- if (charset == FXFONT_HANGEUL_CHARSET) {
- return 1 << 19;
- }
- if (charset == FXFONT_SYMBOL_CHARSET) {
- return 1 << 31;
- }
- return 1 << 21;
-}
-static int CP2CharSet(int cp)
-{
- if(cp == 932) {
- return FXFONT_SHIFTJIS_CHARSET;
- } else if(cp == 936) {
- return FXFONT_GB2312_CHARSET;
- } else if(cp == 949) {
- return FXFONT_HANGEUL_CHARSET;
- } else if(cp == 950) {
- return FXFONT_CHINESEBIG5_CHARSET;
- }
- return FXFONT_DEFAULT_CHARSET;
-}
-FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont, int iBaseFont, int italic_angle, int weight, int picthfamily)
-{
- if (iBaseFont < 12) {
- if (m_FoxitFaces[iBaseFont]) {
- return m_FoxitFaces[iBaseFont];
- }
- FX_LPCBYTE pFontData = NULL;
- FX_DWORD size = 0;
- if (m_pFontMgr->GetStandardFont(pFontData, size, iBaseFont)) {
- m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
- return m_FoxitFaces[iBaseFont];
- }
- }
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_MM;
- pSubstFont->m_ItalicAngle = italic_angle;
- if (weight) {
- pSubstFont->m_Weight = weight;
- }
- if (picthfamily & FXFONT_FF_ROMAN) {
- pSubstFont->m_Weight = pSubstFont->m_Weight * 4 / 5;
- pSubstFont->m_Family = "Chrome Serif";
- if (m_MMFaces[1]) {
- return m_MMFaces[1];
- }
- FX_LPCBYTE pFontData = NULL;
- FX_DWORD size;
- m_pFontMgr->GetStandardFont(pFontData, size, 14);
- m_MMFaces[1] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
- return m_MMFaces[1];
- }
- pSubstFont->m_Family = "Chrome Sans";
- if (m_MMFaces[0]) {
- return m_MMFaces[0];
- }
- FX_LPCBYTE pFontData = NULL;
- FX_DWORD size = 0;
- m_pFontMgr->GetStandardFont(pFontData, size, 15);
- m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
- return m_MMFaces[0];
-}
-const struct _AltFontFamily {
- FX_LPCSTR m_pFontName;
- FX_LPCSTR m_pFontFamily;
-}
-g_AltFontFamilies[] = {
- {"AGaramondPro", "Adobe Garamond Pro"},
- {"BankGothicBT-Medium", "BankGothic Md BT"},
- {"ForteMT", "Forte"},
-};
-extern "C" {
- static int compareFontFamilyString(const void* key, const void* element)
- {
- CFX_ByteString str_key((FX_LPCSTR)key);
- if (str_key.Find(((_AltFontFamily*)element)->m_pFontName) != -1) {
- return 0;
- }
- return FXSYS_stricmp((FX_LPCSTR)key, ((_AltFontFamily*)element)->m_pFontName);
- }
-}
-#define FX_FONT_STYLE_None 0x00
-#define FX_FONT_STYLE_Bold 0x01
-#define FX_FONT_STYLE_Italic 0x02
-#define FX_FONT_STYLE_BoldBold 0x04
-static CFX_ByteString _GetFontFamily(CFX_ByteString fontName, int nStyle)
-{
- if (fontName.Find("Script") >= 0) {
- if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) {
- fontName = "ScriptMTBold";
- } else if (fontName.Find("Palace") >= 0) {
- fontName = "PalaceScriptMT";
- } else if (fontName.Find("French") >= 0) {
- fontName = "FrenchScriptMT";
- } else if (fontName.Find("FreeStyle") >= 0) {
- fontName = "FreeStyleScript";
- }
- return fontName;
- }
- _AltFontFamily* found = (_AltFontFamily*)FXSYS_bsearch((FX_LPCSTR)fontName, g_AltFontFamilies,
- sizeof g_AltFontFamilies / sizeof (_AltFontFamily), sizeof (_AltFontFamily), compareFontFamilyString);
- if (found == NULL) {
- return fontName;
- }
- return found->m_pFontFamily;
-};
-typedef struct _FX_FontStyle {
- FX_LPCSTR style;
- FX_INT32 len;
-} FX_FontStyle;
-const FX_FontStyle g_FontStyles[] = {
- "Bold", 4,
- "Italic", 6,
- "BoldItalic", 10,
- "Reg", 3,
- "Regular", 7,
-};
-CFX_ByteString ParseStyle(FX_LPCSTR pStyle, int iLen, int iIndex)
-{
- CFX_ByteTextBuf buf;
- if (!iLen || iLen <= iIndex) {
- return buf.GetByteString();
- }
- while (iIndex < iLen) {
- if (pStyle[iIndex] == ',') {
- break;
- }
- buf.AppendChar(pStyle[iIndex]);
- ++iIndex;
- }
- return buf.GetByteString();
-}
-FX_INT32 GetStyleType(const CFX_ByteString &bsStyle, FX_BOOL bRevert)
-{
- FX_INT32 iLen = bsStyle.GetLength();
- if (!iLen) {
- return -1;
- }
- int iSize = sizeof(g_FontStyles) / sizeof(FX_FontStyle);
- const FX_FontStyle *pStyle = NULL;
- for (int i = iSize - 1; i >= 0; --i) {
- pStyle = g_FontStyles + i;
- if (!pStyle || pStyle->len > iLen) {
- continue;
- }
- if (!bRevert) {
- if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) {
- return i;
- }
- } else {
- if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) {
- return i;
- }
- }
- }
- return -1;
-}
-FX_BOOL CheckSupportThirdPartFont(CFX_ByteString name, int &PitchFamily)
-{
- if (name == FX_BSTRC("MyriadPro")) {
- PitchFamily &= ~FXFONT_FF_ROMAN;
- return TRUE;
- }
- return FALSE;
-}
-FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, FX_BOOL bTrueType, FX_DWORD flags,
- int weight, int italic_angle, int WindowCP, CFX_SubstFont* pSubstFont)
-{
- if (!(flags & FXFONT_USEEXTERNATTR)) {
- weight = FXFONT_FW_NORMAL;
- italic_angle = 0;
- }
- CFX_ByteString SubstName = name;
- SubstName.Remove(0x20);
- if (bTrueType) {
- if (name[0] == '@') {
- SubstName = name.Mid(1);
- }
- }
- _PDF_GetStandardFontName(SubstName);
- if (SubstName == FX_BSTRC("Symbol") && !bTrueType) {
- pSubstFont->m_Family = "Chrome Symbol";
- pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
- if (m_FoxitFaces[12]) {
- return m_FoxitFaces[12];
- }
- FX_LPCBYTE pFontData = NULL;
- FX_DWORD size = 0;
- m_pFontMgr->GetStandardFont(pFontData, size, 12);
- m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
- return m_FoxitFaces[12];
- }
- if (SubstName == FX_BSTRC("ZapfDingbats")) {
- pSubstFont->m_Family = "Chrome Dingbats";
- pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
- if (m_FoxitFaces[13]) {
- return m_FoxitFaces[13];
- }
- FX_LPCBYTE pFontData = NULL;
- FX_DWORD size = 0;
- m_pFontMgr->GetStandardFont(pFontData, size, 13);
- m_FoxitFaces[13] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
- return m_FoxitFaces[13];
- }
- int iBaseFont = 0;
- CFX_ByteString family, style;
- FX_BOOL bHasComma = FALSE;
- FX_BOOL bHasHypen = FALSE;
- int find = SubstName.Find(FX_BSTRC(","), 0);
- if (find >= 0) {
- family = SubstName.Left(find);
- _PDF_GetStandardFontName(family);
- style = SubstName.Mid(find + 1);
- bHasComma = TRUE;
- } else {
- family = SubstName;
- }
- for (; iBaseFont < 12; iBaseFont ++)
- if (family == CFX_ByteStringC(g_Base14FontNames[iBaseFont])) {
- break;
- }
- int PitchFamily = 0;
- FX_BOOL bItalic = FALSE;
- FX_DWORD nStyle = 0;
- FX_BOOL bStyleAvail = FALSE;
- FX_BOOL bFamilyStyleIsWhole = FALSE;
- FX_BOOL bNextF = FALSE;
- if (iBaseFont < 12) {
- family = g_Base14FontNames[iBaseFont];
- if ((iBaseFont % 4) == 1 || (iBaseFont % 4) == 2) {
- nStyle |= FX_FONT_STYLE_Bold;
- }
- if ((iBaseFont % 4) / 2) {
- nStyle |= FX_FONT_STYLE_Italic;
- }
- if (iBaseFont < 4) {
- PitchFamily |= FXFONT_FF_FIXEDPITCH;
- }
- if (iBaseFont >= 8) {
- PitchFamily |= FXFONT_FF_ROMAN;
- }
- } else {
- if (!bHasComma) {
- find = family.ReverseFind('-');
- if (find >= 0) {
- style = family.Mid(find + 1);
- family = family.Left(find);
- bHasHypen = TRUE;
- }
- }
- if (!bHasHypen) {
- int nLen = family.GetLength();
- FX_INT32 nRet = GetStyleType(family, TRUE);
- if (nRet > -1) {
- family = family.Left(nLen - g_FontStyles[nRet].len);
- if (nRet == 0) {
- nStyle |= FX_FONT_STYLE_Bold;
- }
- if (nRet == 1) {
- nStyle |= FX_FONT_STYLE_Italic;
- }
- if (nRet == 2) {
- nStyle |= (FX_FONT_STYLE_Bold | FX_FONT_STYLE_Italic);
- }
- }
- }
- if (flags & FXFONT_SERIF) {
- PitchFamily |= FXFONT_FF_ROMAN;
- }
- if (flags & FXFONT_SCRIPT) {
- PitchFamily |= FXFONT_FF_SCRIPT;
- }
- if (flags & FXFONT_FIXED_PITCH) {
- PitchFamily |= FXFONT_FF_FIXEDPITCH;
- }
- }
- if (!style.IsEmpty()) {
- int nLen = style.GetLength();
- FX_LPCSTR pStyle = style;
- int i = 0;
- FX_BOOL bFirstItem = TRUE;
- CFX_ByteString buf;
- while (i < nLen) {
- buf = ParseStyle(pStyle, nLen, i);
- FX_INT32 nRet = GetStyleType(buf, FALSE);
- if ((i && !bStyleAvail) || (!i && nRet < 0)) {
- family = SubstName;
- iBaseFont = 12;
- break;
- } else if (nRet >= 0) {
- bStyleAvail = TRUE;
- }
- if (nRet == 0) {
- if (nStyle & FX_FONT_STYLE_Bold) {
- nStyle |= FX_FONT_STYLE_BoldBold;
- } else {
- nStyle |= FX_FONT_STYLE_Bold;
- }
- bFirstItem = FALSE;
- }
- if (nRet == 1) {
- if (bFirstItem) {
- nStyle |= FX_FONT_STYLE_Italic;
- } else {
- family = SubstName;
- iBaseFont = 12;
- }
- break;
- }
- if (nRet == 2) {
- nStyle |= FX_FONT_STYLE_Italic;
- if (nStyle & FX_FONT_STYLE_Bold) {
- nStyle |= FX_FONT_STYLE_BoldBold;
- } else {
- nStyle |= FX_FONT_STYLE_Bold;
- }
- bFirstItem = FALSE;
- }
- i += buf.GetLength() + 1;
- }
- }
- weight = weight ? weight : FXFONT_FW_NORMAL;
- int old_weight = weight;
- if (nStyle) {
- weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL);
- }
- if (nStyle & FX_FONT_STYLE_Italic) {
- bItalic = TRUE;
- }
- FX_BOOL bCJK = FALSE;
- FX_BOOL bExact = FALSE;
- int Charset = FXFONT_ANSI_CHARSET;
- if (WindowCP) {
- Charset = _GetCharsetFromCodePage(WindowCP);
- } else if (iBaseFont == 12 && (flags & FXFONT_SYMBOLIC)) {
- Charset = FXFONT_SYMBOL_CHARSET;
- }
- if (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET ||
- Charset == FXFONT_HANGEUL_CHARSET || Charset == FXFONT_CHINESEBIG5_CHARSET) {
- bCJK = TRUE;
- }
- if (m_pFontInfo == NULL) {
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
- return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily);
- }
- family = _GetFontFamily(family, nStyle);
- CFX_ByteString match = MatchInstalledFonts(_TT_NormalizeName(family));
- if (match.IsEmpty() && family != SubstName && (!bHasComma && (!bHasHypen || (bHasHypen && !bStyleAvail)))) {
- match = MatchInstalledFonts(_TT_NormalizeName(SubstName));
- }
- if (match.IsEmpty() && iBaseFont >= 12) {
- if (!bCJK) {
- if (!CheckSupportThirdPartFont(family, PitchFamily)) {
- if (italic_angle != 0) {
- bItalic = TRUE;
- } else {
- bItalic = FALSE;
- }
- weight = old_weight;
- }
- } else {
- pSubstFont->m_bSubstOfCJK = TRUE;
- if (nStyle) {
- pSubstFont->m_WeightCJK = weight;
- } else {
- pSubstFont->m_WeightCJK = FXFONT_FW_NORMAL;
- }
- if (nStyle & FX_FONT_STYLE_Italic) {
- pSubstFont->m_bItlicCJK = TRUE;
- }
- }
- } else {
- italic_angle = 0;
- weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL);
- }
- if (!match.IsEmpty() || iBaseFont < 12) {
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT;
- if (!match.IsEmpty()) {
- family = match;
- }
- if (iBaseFont < 12) {
- if (nStyle && !(iBaseFont % 4)) {
- if ((nStyle & 0x3) == 1) {
- iBaseFont += 1;
- }
- if ((nStyle & 0x3) == 2) {
- iBaseFont += 3;
- }
- if ((nStyle & 0x3) == 3) {
- iBaseFont += 2;
- }
- }
- if (m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData) {
- if (m_FoxitFaces[iBaseFont]) {
- return m_FoxitFaces[iBaseFont];
- }
- m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData,
- m_pFontMgr->m_ExternalFonts[iBaseFont].m_dwSize, 0);
- if (m_FoxitFaces[iBaseFont]) {
- return m_FoxitFaces[iBaseFont];
- }
- } else {
- family = g_Base14FontNames[iBaseFont];
- }
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
- }
- } else {
- if (flags & FXFONT_ITALIC) {
- bItalic = TRUE;
- }
- }
- bExact = !match.IsEmpty();
- void* hFont = m_pFontInfo->MapFont(weight, bItalic, Charset, PitchFamily, family, bExact);
- if (bExact) {
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT;
- }
- if (hFont == NULL) {
- if (bCJK) {
- if (italic_angle != 0) {
- bItalic = TRUE;
- } else {
- bItalic = FALSE;
- }
- weight = old_weight;
- }
- if (!match.IsEmpty()) {
- hFont = m_pFontInfo->GetFont(match);
- if (hFont == NULL) {
- return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily);
- }
- } else {
- if (Charset == FXFONT_SYMBOL_CHARSET) {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
- if (SubstName == FX_BSTRC("Symbol")) {
- pSubstFont->m_Family = "Chrome Symbol";
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
- pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
- if (m_FoxitFaces[12]) {
- return m_FoxitFaces[12];
- }
- FX_LPCBYTE pFontData = NULL;
- FX_DWORD size = 0;
- m_pFontMgr->GetStandardFont(pFontData, size, 12);
- m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
- return m_FoxitFaces[12];
- } else {
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL;
- return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, weight, italic_angle, 0, pSubstFont);
- }
-#else
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL;
- return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, weight, italic_angle, 0, pSubstFont);
-#endif
- }
- if (Charset == FXFONT_ANSI_CHARSET) {
- pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
- return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily);
- }
- int index = m_CharsetArray.Find(Charset);
- if (index < 0) {
- return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily);
- } else {
- hFont = m_pFontInfo->GetFont(m_FaceArray[index]);
- }
- }
- }
- pSubstFont->m_ExtHandle = m_pFontInfo->RetainFont(hFont);
- if (hFont == NULL) {
- return NULL;
- }
- m_pFontInfo->GetFaceName(hFont, SubstName);
- if (Charset == FXFONT_DEFAULT_CHARSET) {
- m_pFontInfo->GetFontCharset(hFont, Charset);
- }
- FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, NULL, 0);
- FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, NULL, 0);
- if(font_size == 0 && ttc_size == 0) {
- m_pFontInfo->DeleteFont(hFont);
- return NULL;
- }
- FXFT_Face face = NULL;
- if (ttc_size) {
- FX_BYTE temp[1024];
- m_pFontInfo->GetFontData(hFont, 0x74746366, temp, 1024);
- FX_DWORD checksum = 0;
- for (int i = 0; i < 256; i ++) {
- checksum += ((FX_DWORD*)temp)[i];
- }
- FX_LPBYTE pFontData;
- face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, ttc_size - font_size, pFontData);
- if (face == NULL) {
- pFontData = FX_Alloc(FX_BYTE, ttc_size);
- if (pFontData) {
- m_pFontInfo->GetFontData(hFont, 0x74746366, pFontData, ttc_size);
- face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData, ttc_size,
- ttc_size - font_size);
- }
- }
- } else {
- FX_LPBYTE pFontData;
- face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData);
- if (face == NULL) {
- pFontData = FX_Alloc(FX_BYTE, font_size);
- if (!pFontData) {
- m_pFontInfo->DeleteFont(hFont);
- return NULL;
- }
- m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size);
- face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData, font_size, m_pFontInfo->GetFaceIndex(hFont));
- }
- }
- if (face == NULL) {
- m_pFontInfo->DeleteFont(hFont);
- return NULL;
- }
- pSubstFont->m_Family = SubstName;
- pSubstFont->m_Charset = Charset;
- FX_BOOL bNeedUpdateWeight = FALSE;
- if (FXFT_Is_Face_Bold(face)) {
- if (weight == FXFONT_FW_BOLD) {
- bNeedUpdateWeight = FALSE;
- } else {
- bNeedUpdateWeight = TRUE;
- }
- } else {
- if (weight == FXFONT_FW_NORMAL) {
- bNeedUpdateWeight = FALSE;
- } else {
- bNeedUpdateWeight = TRUE;
- }
- }
- if (bNeedUpdateWeight) {
- pSubstFont->m_Weight = weight;
- }
- if (bItalic && !FXFT_Is_Face_Italic(face)) {
- if (italic_angle == 0) {
- italic_angle = -12;
- } else if (FXSYS_abs(italic_angle) < 5) {
- italic_angle = 0;
- }
- pSubstFont->m_ItalicAngle = italic_angle;
- }
- m_pFontInfo->DeleteFont(hFont);
- return face;
-}
-extern "C" {
- unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset,
- unsigned char* buffer, unsigned long count);
- void _FTStreamClose(FXFT_Stream stream);
-};
-CFontFileFaceInfo::CFontFileFaceInfo()
-{
- m_pFile = NULL;
- m_Face = NULL;
- m_Charsets = 0;
- m_FileSize = 0;
- m_FontOffset = 0;
- m_Weight = 0;
- m_bItalic = FALSE;
- m_PitchFamily = 0;
-}
-CFontFileFaceInfo::~CFontFileFaceInfo()
-{
- if (m_Face) {
- FXFT_Done_Face(m_Face);
- }
- m_Face = NULL;
-}
-extern FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream);
-#if defined(_FPDFAPI_MINI_) || _FX_OS_ == _FX_ANDROID_
-IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
-{
- return NULL;
-}
-#endif
-#if !defined(_FPDFAPI_MINI_)
-CFX_FolderFontInfo::CFX_FolderFontInfo()
-{
-}
-CFX_FolderFontInfo::~CFX_FolderFontInfo()
-{
- FX_POSITION pos = m_FontList.GetStartPosition();
- while (pos) {
- CFX_ByteString key;
- FX_LPVOID value;
- m_FontList.GetNextAssoc(pos, key, value);
- delete (CFontFaceInfo*)value;
- }
-}
-void CFX_FolderFontInfo::AddPath(FX_BSTR path)
-{
- m_PathList.Add(path);
-}
-void CFX_FolderFontInfo::Release()
-{
- delete this;
-}
-FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper)
-{
- m_pMapper = pMapper;
- for (int i = 0; i < m_PathList.GetSize(); i ++) {
- ScanPath(m_PathList[i]);
- }
- return TRUE;
-}
-void CFX_FolderFontInfo::ScanPath(CFX_ByteString& path)
-{
- void* handle = FX_OpenFolder(path);
- if (handle == NULL) {
- return;
- }
- CFX_ByteString filename;
- FX_BOOL bFolder;
- while (FX_GetNextFile(handle, filename, bFolder)) {
- if (bFolder) {
- if (filename == "." || filename == "..") {
- continue;
- }
- } else {
- CFX_ByteString ext = filename.Right(4);
- ext.MakeUpper();
- if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC") {
- continue;
- }
- }
- CFX_ByteString fullpath = path;
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
- fullpath += "\\";
-#else
- fullpath += "/";
-#endif
- fullpath += filename;
- if (bFolder) {
- ScanPath(fullpath);
- } else {
- ScanFile(fullpath);
- }
- }
- FX_CloseFolder(handle);
-}
-void CFX_FolderFontInfo::ScanFile(CFX_ByteString& path)
-{
- FXSYS_FILE* pFile = FXSYS_fopen(path, "rb");
- if (pFile == NULL) {
- return;
- }
- FXSYS_fseek(pFile, 0, FXSYS_SEEK_END);
- FX_DWORD filesize = FXSYS_ftell(pFile);
- FX_BYTE buffer[16];
- FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET);
- size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile);
- if (GET_TT_LONG(buffer) == 0x74746366) {
- FX_DWORD nFaces = GET_TT_LONG(buffer + 8);
- FX_LPBYTE offsets = FX_Alloc(FX_BYTE, nFaces * 4);
- if (!offsets) {
- FXSYS_fclose(pFile);
- return;
- }
- readCnt = FXSYS_fread(offsets, nFaces * 4, 1, pFile);
- for (FX_DWORD i = 0; i < nFaces; i ++) {
- FX_LPBYTE p = offsets + i * 4;
- ReportFace(path, pFile, filesize, GET_TT_LONG(p));
- }
- FX_Free(offsets);
- } else {
- ReportFace(path, pFile, filesize, 0);
- }
- FXSYS_fclose(pFile);
-}
-void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path, FXSYS_FILE* pFile, FX_DWORD filesize, FX_DWORD offset)
-{
- FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
- char buffer[16];
- if (!FXSYS_fread(buffer, 12, 1, pFile)) {
- return;
- }
- FX_DWORD nTables = GET_TT_SHORT(buffer + 4);
- CFX_ByteString tables = _FPDF_ReadStringFromFile(pFile, nTables * 16);
- CFX_ByteString names = _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616d65);
- CFX_ByteString facename = _FPDF_GetNameFromTT(names, 1);
- CFX_ByteString style = _FPDF_GetNameFromTT(names, 2);
- if (style != "Regular") {
- facename += " " + style;
- }
- FX_LPVOID p;
- if (m_FontList.Lookup(facename, p)) {
- return;
- }
- CFontFaceInfo* pInfo = FX_NEW CFontFaceInfo;
- if (!pInfo) {
- return;
- }
- pInfo->m_FilePath = path;
- pInfo->m_FaceName = facename;
- pInfo->m_FontTables = tables;
- pInfo->m_FontOffset = offset;
- pInfo->m_FileSize = filesize;
- pInfo->m_Charsets = 0;
- CFX_ByteString os2 = _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x4f532f32);
- if (os2.GetLength() >= 86) {
- FX_LPCBYTE p = (FX_LPCBYTE)os2 + 78;
- FX_DWORD codepages = GET_TT_LONG(p);
- if (codepages & (1 << 17)) {
- m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET);
- pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS;
- }
- if (codepages & (1 << 18)) {
- m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET);
- pInfo->m_Charsets |= CHARSET_FLAG_GB;
- }
- if (codepages & (1 << 20)) {
- m_pMapper->AddInstalledFont(facename, FXFONT_CHINESEBIG5_CHARSET);
- pInfo->m_Charsets |= CHARSET_FLAG_BIG5;
- }
- if ((codepages & (1 << 19)) || (codepages & (1 << 21))) {
- m_pMapper->AddInstalledFont(facename, FXFONT_HANGEUL_CHARSET);
- pInfo->m_Charsets |= CHARSET_FLAG_KOREAN;
- }
- if (codepages & (1 << 31)) {
- m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET);
- pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL;
- }
- }
- m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET);
- pInfo->m_Charsets |= CHARSET_FLAG_ANSI;
- pInfo->m_Styles = 0;
- if (style.Find(FX_BSTRC("Bold")) > -1) {
- pInfo->m_Styles |= FXFONT_BOLD;
- }
- if (style.Find(FX_BSTRC("Italic")) > -1 || style.Find(FX_BSTRC("Oblique")) > -1) {
- pInfo->m_Styles |= FXFONT_ITALIC;
- }
- if (facename.Find(FX_BSTRC("Serif")) > -1) {
- pInfo->m_Styles |= FXFONT_SERIF;
- }
- m_FontList.SetAt(facename, pInfo);
-}
-void* CFX_FolderFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL& bExact)
-{
- return NULL;
-}
-void* CFX_FolderFontInfo::GetFont(FX_LPCSTR face)
-{
- FX_LPVOID p;
- if (!m_FontList.Lookup(face, p)) {
- return NULL;
- }
- return p;
-}
-FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size)
-{
- if (hFont == NULL) {
- return 0;
- }
- CFontFaceInfo* pFont = (CFontFaceInfo*)hFont;
- FXSYS_FILE* pFile = NULL;
- if (size > 0) {
- pFile = FXSYS_fopen(pFont->m_FilePath, "rb");
- if (pFile == NULL) {
- return 0;
- }
- }
- FX_DWORD datasize = 0;
- FX_DWORD offset;
- if (table == 0) {
- datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize;
- offset = 0;
- } else if (table == 0x74746366) {
- datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0;
- offset = 0;
- } else {
- FX_DWORD nTables = pFont->m_FontTables.GetLength() / 16;
- for (FX_DWORD i = 0; i < nTables; i ++) {
- FX_LPCBYTE p = (FX_LPCBYTE)pFont->m_FontTables + i * 16;
- if (GET_TT_LONG(p) == table) {
- offset = GET_TT_LONG(p + 8);
- datasize = GET_TT_LONG(p + 12);
- }
- }
- }
- if (datasize && size >= datasize && pFile) {
- FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
- size_t readCnt = FXSYS_fread(buffer, datasize, 1, pFile);
- }
- if (pFile) {
- FXSYS_fclose(pFile);
- }
- return datasize;
-}
-void CFX_FolderFontInfo::DeleteFont(void* hFont)
-{
-}
-FX_BOOL CFX_FolderFontInfo::GetFaceName(void* hFont, CFX_ByteString& name)
-{
- if (hFont == NULL) {
- return FALSE;
- }
- CFontFaceInfo* pFont = (CFontFaceInfo*)hFont;
- name = pFont->m_FaceName;
- return TRUE;
-}
-FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset)
-{
- return FALSE;
-}
-#endif
+// 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 "../../../include/fxge/fx_ge.h"
+#include "../../../include/fxge/fx_freetype.h"
+#include "text_int.h"
+#define GET_TT_SHORT(w) (FX_WORD)(((w)[0] << 8) | (w)[1])
+#define GET_TT_LONG(w) (FX_DWORD)(((w)[0] << 24) | ((w)[1] << 16) | ((w)[2] << 8) | (w)[3])
+CFX_SubstFont::CFX_SubstFont()
+{
+ m_ExtHandle = NULL;
+ m_Charset = 0;
+ m_SubstFlags = 0;
+ m_Weight = 0;
+ m_ItalicAngle = 0;
+ m_bSubstOfCJK = FALSE;
+ m_WeightCJK = 0;
+ m_bItlicCJK = FALSE;
+}
+CTTFontDesc::~CTTFontDesc()
+{
+ if (m_Type == 1) {
+ if (m_SingleFace.m_pFace) {
+ FXFT_Done_Face(m_SingleFace.m_pFace);
+ }
+ } else if (m_Type == 2) {
+ for (int i = 0; i < 16; i ++)
+ if (m_TTCFace.m_pFaces[i]) {
+ FXFT_Done_Face(m_TTCFace.m_pFaces[i]);
+ }
+ }
+ if (m_pFontData) {
+ FX_Free(m_pFontData);
+ }
+}
+FX_BOOL CTTFontDesc::ReleaseFace(FXFT_Face face)
+{
+ if (m_Type == 1) {
+ if (m_SingleFace.m_pFace != face) {
+ return FALSE;
+ }
+ } else if (m_Type == 2) {
+ int i;
+ for (i = 0; i < 16; i ++)
+ if (m_TTCFace.m_pFaces[i] == face) {
+ break;
+ }
+ if (i == 16) {
+ return FALSE;
+ }
+ }
+ m_RefCount --;
+ if (m_RefCount) {
+ return FALSE;
+ }
+ delete this;
+ return TRUE;
+}
+CFX_FontMgr::CFX_FontMgr()
+{
+ m_pBuiltinMapper = FX_NEW CFX_FontMapper;
+ if (!m_pBuiltinMapper) {
+ return;
+ }
+ m_pBuiltinMapper->m_pFontMgr = this;
+ m_pExtMapper = NULL;
+ m_FTLibrary = NULL;
+ FXSYS_memset32(m_ExternalFonts, 0, sizeof m_ExternalFonts);
+}
+CFX_FontMgr::~CFX_FontMgr()
+{
+ if (m_pBuiltinMapper) {
+ delete m_pBuiltinMapper;
+ }
+ FreeCache();
+ if (m_FTLibrary) {
+ FXFT_Done_FreeType(m_FTLibrary);
+ }
+}
+void CFX_FontMgr::InitFTLibrary()
+{
+ if (m_FTLibrary == NULL) {
+ FXFT_Init_FreeType(&m_FTLibrary);
+ }
+}
+void CFX_FontMgr::FreeCache()
+{
+ FX_POSITION pos = m_FaceMap.GetStartPosition();
+ while(pos) {
+ CFX_ByteString Key;
+ CTTFontDesc* face;
+ m_FaceMap.GetNextAssoc(pos, Key, (void*&)face);
+ delete face;
+ }
+ m_FaceMap.RemoveAll();
+}
+void CFX_FontMgr::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo)
+{
+ m_pBuiltinMapper->SetSystemFontInfo(pFontInfo);
+}
+FXFT_Face CFX_FontMgr::FindSubstFont(const CFX_ByteString& face_name, FX_BOOL bTrueType,
+ FX_DWORD flags, int weight, int italic_angle, int CharsetCP, CFX_SubstFont* pSubstFont)
+{
+ if (m_FTLibrary == NULL) {
+ FXFT_Init_FreeType(&m_FTLibrary);
+ }
+ if (m_pExtMapper) {
+ FXFT_Face face = m_pExtMapper->FindSubstFont(face_name, bTrueType, flags, weight, italic_angle,
+ CharsetCP, pSubstFont);
+ if (face) {
+ return face;
+ }
+ }
+ return m_pBuiltinMapper->FindSubstFont(face_name, bTrueType, flags, weight, italic_angle,
+ CharsetCP, pSubstFont);
+}
+FXFT_Face CFX_FontMgr::GetCachedFace(const CFX_ByteString& face_name,
+ int weight, FX_BOOL bItalic, FX_LPBYTE& pFontData)
+{
+ CFX_ByteString key(face_name);
+ key += ',';
+ key += CFX_ByteString::FormatInteger(weight);
+ key += bItalic ? 'I' : 'N';
+ CTTFontDesc* pFontDesc = NULL;
+ m_FaceMap.Lookup(key, (void*&)pFontDesc);
+ if(pFontDesc) {
+ pFontData = pFontDesc->m_pFontData;
+ pFontDesc->m_RefCount ++;
+ return pFontDesc->m_SingleFace.m_pFace;
+ }
+ return NULL;
+}
+FXFT_Face CFX_FontMgr::AddCachedFace(const CFX_ByteString& face_name,
+ int weight, FX_BOOL bItalic, FX_LPBYTE pData, FX_DWORD size, int face_index)
+{
+ CTTFontDesc* pFontDesc = FX_NEW CTTFontDesc;
+ if (!pFontDesc) {
+ return NULL;
+ }
+ pFontDesc->m_Type = 1;
+ pFontDesc->m_SingleFace.m_pFace = NULL;
+ pFontDesc->m_SingleFace.m_bBold = weight;
+ pFontDesc->m_SingleFace.m_bItalic = bItalic;
+ pFontDesc->m_pFontData = pData;
+ pFontDesc->m_RefCount = 1;
+ FXFT_Library library;
+ if (m_FTLibrary == NULL) {
+ FXFT_Init_FreeType(&m_FTLibrary);
+ }
+ library = m_FTLibrary;
+ int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &pFontDesc->m_SingleFace.m_pFace);
+ if (ret) {
+ delete pFontDesc;
+ return NULL;
+ }
+ ret = FXFT_Set_Pixel_Sizes(pFontDesc->m_SingleFace.m_pFace, 64, 64);
+ if (ret) {
+ delete pFontDesc;
+ return NULL;
+ }
+ CFX_ByteString key(face_name);
+ key += ',';
+ key += CFX_ByteString::FormatInteger(weight);
+ key += bItalic ? 'I' : 'N';
+ m_FaceMap.SetAt(key, pFontDesc);
+ return pFontDesc->m_SingleFace.m_pFace;
+}
+const FX_LPCSTR g_Base14FontNames[14] = {
+ "Courier",
+ "Courier-Bold",
+ "Courier-BoldOblique",
+ "Courier-Oblique",
+ "Helvetica",
+ "Helvetica-Bold",
+ "Helvetica-BoldOblique",
+ "Helvetica-Oblique",
+ "Times-Roman",
+ "Times-Bold",
+ "Times-BoldItalic",
+ "Times-Italic",
+ "Symbol",
+ "ZapfDingbats",
+};
+const struct _AltFontName {
+ const FX_CHAR* m_pName;
+ int m_Index;
+}
+g_AltFontNames[] = {
+ {"Arial", 4},
+ {"Arial,Bold", 5},
+ {"Arial,BoldItalic", 6},
+ {"Arial,Italic", 7},
+ {"Arial-Bold", 5},
+ {"Arial-BoldItalic", 6},
+ {"Arial-BoldItalicMT", 6},
+ {"Arial-BoldMT", 5},
+ {"Arial-Italic", 7},
+ {"Arial-ItalicMT", 7},
+ {"ArialBold", 5},
+ {"ArialBoldItalic", 6},
+ {"ArialItalic", 7},
+ {"ArialMT", 4},
+ {"ArialMT,Bold", 5},
+ {"ArialMT,BoldItalic", 6},
+ {"ArialMT,Italic", 7},
+ {"ArialRoundedMTBold", 5},
+ {"Courier", 0},
+ {"Courier,Bold", 1},
+ {"Courier,BoldItalic", 2},
+ {"Courier,Italic", 3},
+ {"Courier-Bold", 1},
+ {"Courier-BoldOblique", 2},
+ {"Courier-Oblique", 3},
+ {"CourierBold", 1},
+ {"CourierBoldItalic", 2},
+ {"CourierItalic", 3},
+ {"CourierNew", 0},
+ {"CourierNew,Bold", 1},
+ {"CourierNew,BoldItalic", 2},
+ {"CourierNew,Italic", 3},
+ {"CourierNew-Bold", 1},
+ {"CourierNew-BoldItalic", 2},
+ {"CourierNew-Italic", 3},
+ {"CourierNewBold", 1},
+ {"CourierNewBoldItalic", 2},
+ {"CourierNewItalic", 3},
+ {"CourierNewPS-BoldItalicMT", 2},
+ {"CourierNewPS-BoldMT", 1},
+ {"CourierNewPS-ItalicMT", 3},
+ {"CourierNewPSMT", 0},
+ {"CourierStd", 0},
+ {"CourierStd-Bold", 1},
+ {"CourierStd-BoldOblique", 2},
+ {"CourierStd-Oblique", 3},
+ {"Helvetica", 4},
+ {"Helvetica,Bold", 5},
+ {"Helvetica,BoldItalic", 6},
+ {"Helvetica,Italic", 7},
+ {"Helvetica-Bold", 5},
+ {"Helvetica-BoldItalic", 6},
+ {"Helvetica-BoldOblique", 6},
+ {"Helvetica-Italic", 7},
+ {"Helvetica-Oblique", 7},
+ {"HelveticaBold", 5},
+ {"HelveticaBoldItalic", 6},
+ {"HelveticaItalic", 7},
+ {"Symbol", 12},
+ {"SymbolMT", 12},
+ {"Times-Bold", 9},
+ {"Times-BoldItalic", 10},
+ {"Times-Italic", 11},
+ {"Times-Roman", 8},
+ {"TimesBold", 9},
+ {"TimesBoldItalic", 10},
+ {"TimesItalic", 11},
+ {"TimesNewRoman", 8},
+ {"TimesNewRoman,Bold", 9},
+ {"TimesNewRoman,BoldItalic", 10},
+ {"TimesNewRoman,Italic", 11},
+ {"TimesNewRoman-Bold", 9},
+ {"TimesNewRoman-BoldItalic", 10},
+ {"TimesNewRoman-Italic", 11},
+ {"TimesNewRomanBold", 9},
+ {"TimesNewRomanBoldItalic", 10},
+ {"TimesNewRomanItalic", 11},
+ {"TimesNewRomanPS", 8},
+ {"TimesNewRomanPS-Bold", 9},
+ {"TimesNewRomanPS-BoldItalic", 10},
+ {"TimesNewRomanPS-BoldItalicMT", 10},
+ {"TimesNewRomanPS-BoldMT", 9},
+ {"TimesNewRomanPS-Italic", 11},
+ {"TimesNewRomanPS-ItalicMT", 11},
+ {"TimesNewRomanPSMT", 8},
+ {"TimesNewRomanPSMT,Bold", 9},
+ {"TimesNewRomanPSMT,BoldItalic", 10},
+ {"TimesNewRomanPSMT,Italic", 11},
+ {"ZapfDingbats", 13},
+};
+extern "C" {
+ static int compareString(const void* key, const void* element)
+ {
+ return FXSYS_stricmp((FX_LPCSTR)key, ((_AltFontName*)element)->m_pName);
+ }
+}
+int _PDF_GetStandardFontName(CFX_ByteString& name)
+{
+ _AltFontName* found = (_AltFontName*)FXSYS_bsearch((FX_LPCSTR)name, g_AltFontNames,
+ sizeof g_AltFontNames / sizeof (_AltFontName), sizeof (_AltFontName), compareString);
+ if (found == NULL) {
+ return -1;
+ }
+ name = g_Base14FontNames[found->m_Index];
+ return found->m_Index;
+}
+int GetTTCIndex(FX_LPCBYTE pFontData, FX_DWORD ttc_size, FX_DWORD font_offset)
+{
+ int face_index = 0;
+ FX_LPCBYTE p = pFontData + 8;
+ FX_DWORD nfont = GET_TT_LONG(p);
+ FX_DWORD index;
+ for (index = 0; index < nfont; index ++) {
+ p = pFontData + 12 + index * 4;
+ if (GET_TT_LONG(p) == font_offset) {
+ break;
+ }
+ }
+ if(index >= nfont) {
+ face_index = 0;
+ } else {
+ face_index = index;
+ }
+ return face_index;
+}
+FXFT_Face CFX_FontMgr::GetCachedTTCFace(int ttc_size, FX_DWORD checksum,
+ int font_offset, FX_LPBYTE& pFontData)
+{
+ CFX_ByteString key;
+ key.Format("%d:%d", ttc_size, checksum);
+ CTTFontDesc* pFontDesc = NULL;
+ m_FaceMap.Lookup(key, (void*&)pFontDesc);
+ if (pFontDesc == NULL) {
+ return NULL;
+ }
+ pFontData = pFontDesc->m_pFontData;
+ pFontDesc->m_RefCount ++;
+ int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
+ if (pFontDesc->m_TTCFace.m_pFaces[face_index] == NULL) {
+ pFontDesc->m_TTCFace.m_pFaces[face_index] = GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
+ }
+ return pFontDesc->m_TTCFace.m_pFaces[face_index];
+}
+FXFT_Face CFX_FontMgr::AddCachedTTCFace(int ttc_size, FX_DWORD checksum,
+ FX_LPBYTE pData, FX_DWORD size, int font_offset)
+{
+ CFX_ByteString key;
+ key.Format("%d:%d", ttc_size, checksum);
+ CTTFontDesc* pFontDesc = FX_NEW CTTFontDesc;
+ if (!pFontDesc) {
+ return NULL;
+ }
+ pFontDesc->m_Type = 2;
+ pFontDesc->m_pFontData = pData;
+ for (int i = 0; i < 16; i ++) {
+ pFontDesc->m_TTCFace.m_pFaces[i] = NULL;
+ }
+ pFontDesc->m_RefCount ++;
+ key.Format("%d:%d", ttc_size, checksum);
+ m_FaceMap.SetAt(key, pFontDesc);
+ int face_index = GetTTCIndex(pFontDesc->m_pFontData, ttc_size, font_offset);
+ pFontDesc->m_TTCFace.m_pFaces[face_index] = GetFixedFace(pFontDesc->m_pFontData, ttc_size, face_index);
+ return pFontDesc->m_TTCFace.m_pFaces[face_index];
+}
+FXFT_Face CFX_FontMgr::GetFixedFace(FX_LPCBYTE pData, FX_DWORD size, int face_index)
+{
+ FXFT_Library library;
+ if (m_FTLibrary == NULL) {
+ FXFT_Init_FreeType(&m_FTLibrary);
+ }
+ library = m_FTLibrary;
+ FXFT_Face face = NULL;
+ int ret = FXFT_New_Memory_Face(library, pData, size, face_index, &face);
+ if (ret) {
+ return NULL;
+ }
+ ret = FXFT_Set_Pixel_Sizes(face, 64, 64);
+ if (ret) {
+ return NULL;
+ }
+ return face;
+}
+FXFT_Face CFX_FontMgr::GetFileFace(FX_LPCSTR filename, int face_index)
+{
+ FXFT_Library library;
+ if (m_FTLibrary == NULL) {
+ FXFT_Init_FreeType(&m_FTLibrary);
+ }
+ library = m_FTLibrary;
+ FXFT_Face face = NULL;
+ int ret = FXFT_New_Face(library, filename, face_index, &face);
+ if (ret) {
+ return NULL;
+ }
+ ret = FXFT_Set_Pixel_Sizes(face, 64, 64);
+ if (ret) {
+ return NULL;
+ }
+ return face;
+}
+void CFX_FontMgr::ReleaseFace(FXFT_Face face)
+{
+ if (face == NULL) {
+ return;
+ }
+ FX_POSITION pos = m_FaceMap.GetStartPosition();
+ while(pos) {
+ CFX_ByteString Key;
+ CTTFontDesc* ttface;
+ m_FaceMap.GetNextAssoc(pos, Key, (void*&)ttface);
+ if (ttface->ReleaseFace(face)) {
+ m_FaceMap.RemoveKey(Key);
+ }
+ }
+}
+extern "C" {
+ extern const unsigned char g_FoxitFixedItalicFontData [18746];
+ extern const unsigned char g_FoxitFixedFontData [17597];
+ extern const unsigned char g_FoxitSansItalicFontData [16339];
+ extern const unsigned char g_FoxitSansFontData [15025];
+ extern const unsigned char g_FoxitSerifItalicFontData [21227];
+ extern const unsigned char g_FoxitSerifFontData [19469];
+ extern const unsigned char g_FoxitFixedBoldItalicFontData [19151];
+ extern const unsigned char g_FoxitFixedBoldFontData [18055];
+ extern const unsigned char g_FoxitSansBoldItalicFontData [16418];
+ extern const unsigned char g_FoxitSansBoldFontData [16344];
+ extern const unsigned char g_FoxitSerifBoldItalicFontData [20733];
+ extern const unsigned char g_FoxitSerifBoldFontData [19395];
+ extern const unsigned char g_FoxitSymbolFontData[16729];
+ extern const unsigned char g_FoxitDingbatsFontData[29513];
+ extern const unsigned char g_FoxitSerifMMFontData[113417];
+ extern const unsigned char g_FoxitSansMMFontData[66919];
+};
+const FoxitFonts g_FoxitFonts[14] = {
+ {g_FoxitFixedFontData, 17597},
+ {g_FoxitFixedBoldFontData, 18055},
+ {g_FoxitFixedBoldItalicFontData, 19151},
+ {g_FoxitFixedItalicFontData, 18746},
+ {g_FoxitSansFontData, 15025},
+ {g_FoxitSansBoldFontData, 16344},
+ {g_FoxitSansBoldItalicFontData, 16418},
+ {g_FoxitSansItalicFontData, 16339},
+ {g_FoxitSerifFontData, 19469},
+ {g_FoxitSerifBoldFontData, 19395},
+ {g_FoxitSerifBoldItalicFontData, 20733},
+ {g_FoxitSerifItalicFontData, 21227},
+ {g_FoxitSymbolFontData, 16729},
+ {g_FoxitDingbatsFontData, 29513},
+};
+void _FPDFAPI_GetInternalFontData(int id, FX_LPCBYTE& data, FX_DWORD& size)
+{
+ CFX_GEModule::Get()->GetFontMgr()->GetStandardFont(data, size, id);
+}
+FX_BOOL CFX_FontMgr::GetStandardFont(FX_LPCBYTE& pFontData, FX_DWORD& size, int index)
+{
+ if (index > 15 || index < 0) {
+ return FALSE;
+ }
+ {
+ if (index >= 14) {
+ if (index == 14) {
+ pFontData = g_FoxitSerifMMFontData;
+ size = 113417;
+ } else {
+ pFontData = g_FoxitSansMMFontData;
+ size = 66919;
+ }
+ } else {
+ pFontData = g_FoxitFonts[index].m_pFontData;
+ size = g_FoxitFonts[index].m_dwSize;
+ }
+ }
+ return TRUE;
+}
+CFX_FontMapper::CFX_FontMapper()
+{
+ FXSYS_memset32(m_FoxitFaces, 0, sizeof m_FoxitFaces);
+ m_MMFaces[0] = m_MMFaces[1] = NULL;
+ m_pFontInfo = NULL;
+ m_bListLoaded = FALSE;
+ m_pFontEnumerator = NULL;
+}
+CFX_FontMapper::~CFX_FontMapper()
+{
+ for (int i = 0; i < 14; i ++)
+ if (m_FoxitFaces[i]) {
+ FXFT_Done_Face(m_FoxitFaces[i]);
+ }
+ if (m_MMFaces[0]) {
+ FXFT_Done_Face(m_MMFaces[0]);
+ }
+ if (m_MMFaces[1]) {
+ FXFT_Done_Face(m_MMFaces[1]);
+ }
+ if (m_pFontInfo) {
+ m_pFontInfo->Release();
+ }
+}
+void CFX_FontMapper::SetSystemFontInfo(IFX_SystemFontInfo* pFontInfo)
+{
+ if (pFontInfo == NULL) {
+ return;
+ }
+ if (m_pFontInfo) {
+ m_pFontInfo->Release();
+ }
+ m_pFontInfo = pFontInfo;
+}
+static CFX_ByteString _TT_NormalizeName(FX_LPCSTR family)
+{
+ CFX_ByteString norm(family, -1);
+ norm.Remove(' ');
+ norm.Remove('-');
+ norm.Remove(',');
+ int pos = norm.Find('+');
+ if (pos > 0) {
+ norm = norm.Left(pos);
+ }
+ norm.MakeLower();
+ return norm;
+}
+CFX_ByteString _FPDF_GetNameFromTT(FX_LPCBYTE name_table, FX_DWORD name_id)
+{
+ FX_LPCBYTE ptr = name_table + 2;
+ int name_count = GET_TT_SHORT(ptr);
+ int string_offset = GET_TT_SHORT(ptr + 2);
+ FX_LPCBYTE string_ptr = name_table + string_offset;
+ ptr += 4;
+ for (int i = 0; i < name_count; i ++) {
+ if (GET_TT_SHORT(ptr + 6) == name_id && GET_TT_SHORT(ptr) == 1 && GET_TT_SHORT(ptr + 2) == 0) {
+ return CFX_ByteStringC(string_ptr + GET_TT_SHORT(ptr + 10), GET_TT_SHORT(ptr + 8));
+ }
+ ptr += 12;
+ }
+ return CFX_ByteString();
+}
+static CFX_ByteString _FPDF_ReadStringFromFile(FXSYS_FILE* pFile, FX_DWORD size)
+{
+ CFX_ByteString buffer;
+ if (!FXSYS_fread(buffer.GetBuffer(size), size, 1, pFile)) {
+ return CFX_ByteString();
+ }
+ buffer.ReleaseBuffer(size);
+ return buffer;
+}
+static CFX_ByteString _FPDF_ReadStringFromStreamFile(IFX_FileStream* pFile, FX_DWORD size)
+{
+ CFX_ByteString buffer;
+ if (!pFile->ReadBlock(buffer.GetBuffer(size), size)) {
+ return CFX_ByteString();
+ }
+ buffer.ReleaseBuffer(size);
+ return buffer;
+}
+CFX_ByteString _FPDF_LoadTableFromTT(FXSYS_FILE* pFile, FX_LPCBYTE pTables, FX_DWORD nTables, FX_DWORD tag)
+{
+ for (FX_DWORD i = 0; i < nTables; i ++) {
+ FX_LPCBYTE p = pTables + i * 16;
+ if (GET_TT_LONG(p) == tag) {
+ FX_DWORD offset = GET_TT_LONG(p + 8);
+ FX_DWORD size = GET_TT_LONG(p + 12);
+ FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
+ return _FPDF_ReadStringFromFile(pFile, size);
+ }
+ }
+ return CFX_ByteString();
+}
+CFX_ByteString _FPDF_LoadTableFromTTStreamFile(IFX_FileStream* pFile, FX_LPCBYTE pTables, FX_DWORD nTables, FX_DWORD tag)
+{
+ for (FX_DWORD i = 0; i < nTables; i ++) {
+ FX_LPCBYTE p = pTables + i * 16;
+ if (GET_TT_LONG(p) == tag) {
+ FX_DWORD offset = GET_TT_LONG(p + 8);
+ FX_DWORD size = GET_TT_LONG(p + 12);
+ CFX_ByteString buffer;
+ if (!pFile->ReadBlock(buffer.GetBuffer(size), offset, size)) {
+ return CFX_ByteString();
+ }
+ buffer.ReleaseBuffer(size);
+ return buffer;
+ }
+ }
+ return CFX_ByteString();
+}
+CFX_ByteString CFX_FontMapper::GetPSNameFromTT(void* hFont)
+{
+ if (m_pFontInfo == NULL) {
+ CFX_ByteString();
+ }
+ CFX_ByteString result;
+ FX_DWORD size = m_pFontInfo->GetFontData(hFont, 0x6e616d65, NULL, 0);
+ if (size) {
+ FX_LPBYTE buffer = FX_Alloc(FX_BYTE, size);
+ if (!buffer) {
+ return result;
+ }
+ m_pFontInfo->GetFontData(hFont, 0x6e616d65, buffer, size);
+ result = _FPDF_GetNameFromTT(buffer, 6);
+ FX_Free(buffer);
+ }
+ return result;
+}
+void CFX_FontMapper::AddInstalledFont(const CFX_ByteString& name, int charset)
+{
+ if (m_pFontInfo == NULL) {
+ return;
+ }
+ if (m_CharsetArray.Find((FX_DWORD)charset) == -1) {
+ m_CharsetArray.Add((FX_DWORD)charset);
+ m_FaceArray.Add(name);
+ }
+ if (name == m_LastFamily) {
+ return;
+ }
+ FX_LPCBYTE ptr = name;
+ FX_BOOL bLocalized = FALSE;
+ for (int i = 0; i < name.GetLength(); i ++)
+ if (ptr[i] > 0x80) {
+ bLocalized = TRUE;
+ break;
+ }
+ if (bLocalized) {
+ void* hFont = m_pFontInfo->GetFont(name);
+ if (hFont == NULL) {
+ FX_BOOL bExact;
+ hFont = m_pFontInfo->MapFont(0, 0, FXFONT_DEFAULT_CHARSET, 0, name, bExact);
+ if (hFont == NULL) {
+ return;
+ }
+ }
+ CFX_ByteString new_name = GetPSNameFromTT(hFont);
+ if (!new_name.IsEmpty()) {
+ new_name.Insert(0, ' ');
+ m_InstalledTTFonts.Add(new_name);
+ }
+ m_pFontInfo->DeleteFont(hFont);
+ }
+ m_InstalledTTFonts.Add(name);
+ m_LastFamily = name;
+}
+void CFX_FontMapper::LoadInstalledFonts()
+{
+ if (m_pFontInfo == NULL) {
+ return;
+ }
+ if (m_bListLoaded) {
+ return;
+ }
+ if (m_bListLoaded) {
+ return;
+ }
+ m_pFontInfo->EnumFontList(this);
+ m_bListLoaded = TRUE;
+}
+CFX_ByteString CFX_FontMapper::MatchInstalledFonts(const CFX_ByteString& norm_name)
+{
+ LoadInstalledFonts();
+ int i;
+ for (i = m_InstalledTTFonts.GetSize() - 1; i >= 0; i --) {
+ CFX_ByteString norm1 = _TT_NormalizeName(m_InstalledTTFonts[i]);
+ if (norm1 == norm_name) {
+ break;
+ }
+ }
+ if (i < 0) {
+ return CFX_ByteString();
+ }
+ CFX_ByteString match = m_InstalledTTFonts[i];
+ if (match[0] == ' ') {
+ match = m_InstalledTTFonts[i + 1];
+ }
+ return match;
+}
+typedef struct _CHARSET_MAP_ {
+ FX_BYTE charset;
+ FX_WORD codepage;
+} CHARSET_MAP;
+static const CHARSET_MAP g_Codepage2CharsetTable[] = {
+ { 1 , 0 },
+ { 2 , 42 },
+ { 254, 437 },
+ { 255, 850 },
+ { 222, 874 },
+ { 128, 932 },
+ { 134, 936 },
+ { 129, 949 },
+ { 136, 950 },
+ { 238, 1250 },
+ { 204, 1251 },
+ { 0, 1252 },
+ { 161, 1253 },
+ { 162, 1254 },
+ { 177, 1255 },
+ { 178, 1256 },
+ { 186, 1257 },
+ { 163, 1258 },
+ { 130, 1361 },
+ { 77, 10000 },
+ { 78, 10001 },
+ { 79, 10003 },
+ { 80, 10008 },
+ { 81, 10002 },
+ { 83, 10005 },
+ { 84, 10004 },
+ { 85, 10006 },
+ { 86, 10081 },
+ { 87, 10021 },
+ { 88, 10029 },
+ { 89, 10007 },
+};
+FX_BYTE _GetCharsetFromCodePage(FX_WORD codepage)
+{
+ FX_INT32 iEnd = sizeof(g_Codepage2CharsetTable) / sizeof(CHARSET_MAP) - 1;
+ FXSYS_assert(iEnd >= 0);
+ FX_INT32 iStart = 0, iMid;
+ do {
+ iMid = (iStart + iEnd) / 2;
+ const CHARSET_MAP & cp = g_Codepage2CharsetTable[iMid];
+ if (codepage == cp.codepage) {
+ return cp.charset;
+ } else if (codepage < cp.codepage) {
+ iEnd = iMid - 1;
+ } else {
+ iStart = iMid + 1;
+ }
+ } while (iStart <= iEnd);
+ return 1;
+}
+FX_DWORD _GetCodePageRangeFromCharset(int charset)
+{
+ if (charset == FXFONT_EASTEUROPE_CHARSET) {
+ return 1 << 1;
+ }
+ if (charset == FXFONT_GREEK_CHARSET) {
+ return 1 << 3;
+ }
+ if (charset == FXFONT_TURKISH_CHARSET) {
+ return 1 << 4;
+ }
+ if (charset == FXFONT_HEBREW_CHARSET) {
+ return 1 << 5;
+ }
+ if (charset == FXFONT_ARABIC_CHARSET) {
+ return 1 << 6;
+ }
+ if (charset == FXFONT_BALTIC_CHARSET) {
+ return 1 << 7;
+ }
+ if (charset == FXFONT_THAI_CHARSET) {
+ return 1 << 16;
+ }
+ if (charset == FXFONT_SHIFTJIS_CHARSET) {
+ return 1 << 17;
+ }
+ if (charset == FXFONT_GB2312_CHARSET) {
+ return 1 << 18;
+ }
+ if (charset == FXFONT_CHINESEBIG5_CHARSET) {
+ return 1 << 20;
+ }
+ if (charset == FXFONT_HANGEUL_CHARSET) {
+ return 1 << 19;
+ }
+ if (charset == FXFONT_SYMBOL_CHARSET) {
+ return 1 << 31;
+ }
+ return 1 << 21;
+}
+static int CP2CharSet(int cp)
+{
+ if(cp == 932) {
+ return FXFONT_SHIFTJIS_CHARSET;
+ } else if(cp == 936) {
+ return FXFONT_GB2312_CHARSET;
+ } else if(cp == 949) {
+ return FXFONT_HANGEUL_CHARSET;
+ } else if(cp == 950) {
+ return FXFONT_CHINESEBIG5_CHARSET;
+ }
+ return FXFONT_DEFAULT_CHARSET;
+}
+FXFT_Face CFX_FontMapper::UseInternalSubst(CFX_SubstFont* pSubstFont, int iBaseFont, int italic_angle, int weight, int picthfamily)
+{
+ if (iBaseFont < 12) {
+ if (m_FoxitFaces[iBaseFont]) {
+ return m_FoxitFaces[iBaseFont];
+ }
+ FX_LPCBYTE pFontData = NULL;
+ FX_DWORD size = 0;
+ if (m_pFontMgr->GetStandardFont(pFontData, size, iBaseFont)) {
+ m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
+ return m_FoxitFaces[iBaseFont];
+ }
+ }
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_MM;
+ pSubstFont->m_ItalicAngle = italic_angle;
+ if (weight) {
+ pSubstFont->m_Weight = weight;
+ }
+ if (picthfamily & FXFONT_FF_ROMAN) {
+ pSubstFont->m_Weight = pSubstFont->m_Weight * 4 / 5;
+ pSubstFont->m_Family = "Chrome Serif";
+ if (m_MMFaces[1]) {
+ return m_MMFaces[1];
+ }
+ FX_LPCBYTE pFontData = NULL;
+ FX_DWORD size;
+ m_pFontMgr->GetStandardFont(pFontData, size, 14);
+ m_MMFaces[1] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
+ return m_MMFaces[1];
+ }
+ pSubstFont->m_Family = "Chrome Sans";
+ if (m_MMFaces[0]) {
+ return m_MMFaces[0];
+ }
+ FX_LPCBYTE pFontData = NULL;
+ FX_DWORD size = 0;
+ m_pFontMgr->GetStandardFont(pFontData, size, 15);
+ m_MMFaces[0] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
+ return m_MMFaces[0];
+}
+const struct _AltFontFamily {
+ FX_LPCSTR m_pFontName;
+ FX_LPCSTR m_pFontFamily;
+}
+g_AltFontFamilies[] = {
+ {"AGaramondPro", "Adobe Garamond Pro"},
+ {"BankGothicBT-Medium", "BankGothic Md BT"},
+ {"ForteMT", "Forte"},
+};
+extern "C" {
+ static int compareFontFamilyString(const void* key, const void* element)
+ {
+ CFX_ByteString str_key((FX_LPCSTR)key);
+ if (str_key.Find(((_AltFontFamily*)element)->m_pFontName) != -1) {
+ return 0;
+ }
+ return FXSYS_stricmp((FX_LPCSTR)key, ((_AltFontFamily*)element)->m_pFontName);
+ }
+}
+#define FX_FONT_STYLE_None 0x00
+#define FX_FONT_STYLE_Bold 0x01
+#define FX_FONT_STYLE_Italic 0x02
+#define FX_FONT_STYLE_BoldBold 0x04
+static CFX_ByteString _GetFontFamily(CFX_ByteString fontName, int nStyle)
+{
+ if (fontName.Find("Script") >= 0) {
+ if ((nStyle & FX_FONT_STYLE_Bold) == FX_FONT_STYLE_Bold) {
+ fontName = "ScriptMTBold";
+ } else if (fontName.Find("Palace") >= 0) {
+ fontName = "PalaceScriptMT";
+ } else if (fontName.Find("French") >= 0) {
+ fontName = "FrenchScriptMT";
+ } else if (fontName.Find("FreeStyle") >= 0) {
+ fontName = "FreeStyleScript";
+ }
+ return fontName;
+ }
+ _AltFontFamily* found = (_AltFontFamily*)FXSYS_bsearch((FX_LPCSTR)fontName, g_AltFontFamilies,
+ sizeof g_AltFontFamilies / sizeof (_AltFontFamily), sizeof (_AltFontFamily), compareFontFamilyString);
+ if (found == NULL) {
+ return fontName;
+ }
+ return found->m_pFontFamily;
+};
+typedef struct _FX_FontStyle {
+ FX_LPCSTR style;
+ FX_INT32 len;
+} FX_FontStyle;
+const FX_FontStyle g_FontStyles[] = {
+ "Bold", 4,
+ "Italic", 6,
+ "BoldItalic", 10,
+ "Reg", 3,
+ "Regular", 7,
+};
+CFX_ByteString ParseStyle(FX_LPCSTR pStyle, int iLen, int iIndex)
+{
+ CFX_ByteTextBuf buf;
+ if (!iLen || iLen <= iIndex) {
+ return buf.GetByteString();
+ }
+ while (iIndex < iLen) {
+ if (pStyle[iIndex] == ',') {
+ break;
+ }
+ buf.AppendChar(pStyle[iIndex]);
+ ++iIndex;
+ }
+ return buf.GetByteString();
+}
+FX_INT32 GetStyleType(const CFX_ByteString &bsStyle, FX_BOOL bRevert)
+{
+ FX_INT32 iLen = bsStyle.GetLength();
+ if (!iLen) {
+ return -1;
+ }
+ int iSize = sizeof(g_FontStyles) / sizeof(FX_FontStyle);
+ const FX_FontStyle *pStyle = NULL;
+ for (int i = iSize - 1; i >= 0; --i) {
+ pStyle = g_FontStyles + i;
+ if (!pStyle || pStyle->len > iLen) {
+ continue;
+ }
+ if (!bRevert) {
+ if (bsStyle.Left(pStyle->len).Compare(pStyle->style) == 0) {
+ return i;
+ }
+ } else {
+ if (bsStyle.Right(pStyle->len).Compare(pStyle->style) == 0) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+FX_BOOL CheckSupportThirdPartFont(CFX_ByteString name, int &PitchFamily)
+{
+ if (name == FX_BSTRC("MyriadPro")) {
+ PitchFamily &= ~FXFONT_FF_ROMAN;
+ return TRUE;
+ }
+ return FALSE;
+}
+FXFT_Face CFX_FontMapper::FindSubstFont(const CFX_ByteString& name, FX_BOOL bTrueType, FX_DWORD flags,
+ int weight, int italic_angle, int WindowCP, CFX_SubstFont* pSubstFont)
+{
+ if (!(flags & FXFONT_USEEXTERNATTR)) {
+ weight = FXFONT_FW_NORMAL;
+ italic_angle = 0;
+ }
+ CFX_ByteString SubstName = name;
+ SubstName.Remove(0x20);
+ if (bTrueType) {
+ if (name[0] == '@') {
+ SubstName = name.Mid(1);
+ }
+ }
+ _PDF_GetStandardFontName(SubstName);
+ if (SubstName == FX_BSTRC("Symbol") && !bTrueType) {
+ pSubstFont->m_Family = "Chrome Symbol";
+ pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
+ if (m_FoxitFaces[12]) {
+ return m_FoxitFaces[12];
+ }
+ FX_LPCBYTE pFontData = NULL;
+ FX_DWORD size = 0;
+ m_pFontMgr->GetStandardFont(pFontData, size, 12);
+ m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
+ return m_FoxitFaces[12];
+ }
+ if (SubstName == FX_BSTRC("ZapfDingbats")) {
+ pSubstFont->m_Family = "Chrome Dingbats";
+ pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
+ if (m_FoxitFaces[13]) {
+ return m_FoxitFaces[13];
+ }
+ FX_LPCBYTE pFontData = NULL;
+ FX_DWORD size = 0;
+ m_pFontMgr->GetStandardFont(pFontData, size, 13);
+ m_FoxitFaces[13] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
+ return m_FoxitFaces[13];
+ }
+ int iBaseFont = 0;
+ CFX_ByteString family, style;
+ FX_BOOL bHasComma = FALSE;
+ FX_BOOL bHasHypen = FALSE;
+ int find = SubstName.Find(FX_BSTRC(","), 0);
+ if (find >= 0) {
+ family = SubstName.Left(find);
+ _PDF_GetStandardFontName(family);
+ style = SubstName.Mid(find + 1);
+ bHasComma = TRUE;
+ } else {
+ family = SubstName;
+ }
+ for (; iBaseFont < 12; iBaseFont ++)
+ if (family == CFX_ByteStringC(g_Base14FontNames[iBaseFont])) {
+ break;
+ }
+ int PitchFamily = 0;
+ FX_BOOL bItalic = FALSE;
+ FX_DWORD nStyle = 0;
+ FX_BOOL bStyleAvail = FALSE;
+ FX_BOOL bFamilyStyleIsWhole = FALSE;
+ FX_BOOL bNextF = FALSE;
+ if (iBaseFont < 12) {
+ family = g_Base14FontNames[iBaseFont];
+ if ((iBaseFont % 4) == 1 || (iBaseFont % 4) == 2) {
+ nStyle |= FX_FONT_STYLE_Bold;
+ }
+ if ((iBaseFont % 4) / 2) {
+ nStyle |= FX_FONT_STYLE_Italic;
+ }
+ if (iBaseFont < 4) {
+ PitchFamily |= FXFONT_FF_FIXEDPITCH;
+ }
+ if (iBaseFont >= 8) {
+ PitchFamily |= FXFONT_FF_ROMAN;
+ }
+ } else {
+ if (!bHasComma) {
+ find = family.ReverseFind('-');
+ if (find >= 0) {
+ style = family.Mid(find + 1);
+ family = family.Left(find);
+ bHasHypen = TRUE;
+ }
+ }
+ if (!bHasHypen) {
+ int nLen = family.GetLength();
+ FX_INT32 nRet = GetStyleType(family, TRUE);
+ if (nRet > -1) {
+ family = family.Left(nLen - g_FontStyles[nRet].len);
+ if (nRet == 0) {
+ nStyle |= FX_FONT_STYLE_Bold;
+ }
+ if (nRet == 1) {
+ nStyle |= FX_FONT_STYLE_Italic;
+ }
+ if (nRet == 2) {
+ nStyle |= (FX_FONT_STYLE_Bold | FX_FONT_STYLE_Italic);
+ }
+ }
+ }
+ if (flags & FXFONT_SERIF) {
+ PitchFamily |= FXFONT_FF_ROMAN;
+ }
+ if (flags & FXFONT_SCRIPT) {
+ PitchFamily |= FXFONT_FF_SCRIPT;
+ }
+ if (flags & FXFONT_FIXED_PITCH) {
+ PitchFamily |= FXFONT_FF_FIXEDPITCH;
+ }
+ }
+ if (!style.IsEmpty()) {
+ int nLen = style.GetLength();
+ FX_LPCSTR pStyle = style;
+ int i = 0;
+ FX_BOOL bFirstItem = TRUE;
+ CFX_ByteString buf;
+ while (i < nLen) {
+ buf = ParseStyle(pStyle, nLen, i);
+ FX_INT32 nRet = GetStyleType(buf, FALSE);
+ if ((i && !bStyleAvail) || (!i && nRet < 0)) {
+ family = SubstName;
+ iBaseFont = 12;
+ break;
+ } else if (nRet >= 0) {
+ bStyleAvail = TRUE;
+ }
+ if (nRet == 0) {
+ if (nStyle & FX_FONT_STYLE_Bold) {
+ nStyle |= FX_FONT_STYLE_BoldBold;
+ } else {
+ nStyle |= FX_FONT_STYLE_Bold;
+ }
+ bFirstItem = FALSE;
+ }
+ if (nRet == 1) {
+ if (bFirstItem) {
+ nStyle |= FX_FONT_STYLE_Italic;
+ } else {
+ family = SubstName;
+ iBaseFont = 12;
+ }
+ break;
+ }
+ if (nRet == 2) {
+ nStyle |= FX_FONT_STYLE_Italic;
+ if (nStyle & FX_FONT_STYLE_Bold) {
+ nStyle |= FX_FONT_STYLE_BoldBold;
+ } else {
+ nStyle |= FX_FONT_STYLE_Bold;
+ }
+ bFirstItem = FALSE;
+ }
+ i += buf.GetLength() + 1;
+ }
+ }
+ weight = weight ? weight : FXFONT_FW_NORMAL;
+ int old_weight = weight;
+ if (nStyle) {
+ weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL);
+ }
+ if (nStyle & FX_FONT_STYLE_Italic) {
+ bItalic = TRUE;
+ }
+ FX_BOOL bCJK = FALSE;
+ FX_BOOL bExact = FALSE;
+ int Charset = FXFONT_ANSI_CHARSET;
+ if (WindowCP) {
+ Charset = _GetCharsetFromCodePage(WindowCP);
+ } else if (iBaseFont == 12 && (flags & FXFONT_SYMBOLIC)) {
+ Charset = FXFONT_SYMBOL_CHARSET;
+ }
+ if (Charset == FXFONT_SHIFTJIS_CHARSET || Charset == FXFONT_GB2312_CHARSET ||
+ Charset == FXFONT_HANGEUL_CHARSET || Charset == FXFONT_CHINESEBIG5_CHARSET) {
+ bCJK = TRUE;
+ }
+ if (m_pFontInfo == NULL) {
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
+ return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily);
+ }
+ family = _GetFontFamily(family, nStyle);
+ CFX_ByteString match = MatchInstalledFonts(_TT_NormalizeName(family));
+ if (match.IsEmpty() && family != SubstName && (!bHasComma && (!bHasHypen || (bHasHypen && !bStyleAvail)))) {
+ match = MatchInstalledFonts(_TT_NormalizeName(SubstName));
+ }
+ if (match.IsEmpty() && iBaseFont >= 12) {
+ if (!bCJK) {
+ if (!CheckSupportThirdPartFont(family, PitchFamily)) {
+ if (italic_angle != 0) {
+ bItalic = TRUE;
+ } else {
+ bItalic = FALSE;
+ }
+ weight = old_weight;
+ }
+ } else {
+ pSubstFont->m_bSubstOfCJK = TRUE;
+ if (nStyle) {
+ pSubstFont->m_WeightCJK = weight;
+ } else {
+ pSubstFont->m_WeightCJK = FXFONT_FW_NORMAL;
+ }
+ if (nStyle & FX_FONT_STYLE_Italic) {
+ pSubstFont->m_bItlicCJK = TRUE;
+ }
+ }
+ } else {
+ italic_angle = 0;
+ weight = nStyle & FX_FONT_STYLE_BoldBold ? 900 : (nStyle & FX_FONT_STYLE_Bold ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL);
+ }
+ if (!match.IsEmpty() || iBaseFont < 12) {
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT;
+ if (!match.IsEmpty()) {
+ family = match;
+ }
+ if (iBaseFont < 12) {
+ if (nStyle && !(iBaseFont % 4)) {
+ if ((nStyle & 0x3) == 1) {
+ iBaseFont += 1;
+ }
+ if ((nStyle & 0x3) == 2) {
+ iBaseFont += 3;
+ }
+ if ((nStyle & 0x3) == 3) {
+ iBaseFont += 2;
+ }
+ }
+ if (m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData) {
+ if (m_FoxitFaces[iBaseFont]) {
+ return m_FoxitFaces[iBaseFont];
+ }
+ m_FoxitFaces[iBaseFont] = m_pFontMgr->GetFixedFace(m_pFontMgr->m_ExternalFonts[iBaseFont].m_pFontData,
+ m_pFontMgr->m_ExternalFonts[iBaseFont].m_dwSize, 0);
+ if (m_FoxitFaces[iBaseFont]) {
+ return m_FoxitFaces[iBaseFont];
+ }
+ } else {
+ family = g_Base14FontNames[iBaseFont];
+ }
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
+ }
+ } else {
+ if (flags & FXFONT_ITALIC) {
+ bItalic = TRUE;
+ }
+ }
+ bExact = !match.IsEmpty();
+ void* hFont = m_pFontInfo->MapFont(weight, bItalic, Charset, PitchFamily, family, bExact);
+ if (bExact) {
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_EXACT;
+ }
+ if (hFont == NULL) {
+ if (bCJK) {
+ if (italic_angle != 0) {
+ bItalic = TRUE;
+ } else {
+ bItalic = FALSE;
+ }
+ weight = old_weight;
+ }
+ if (!match.IsEmpty()) {
+ hFont = m_pFontInfo->GetFont(match);
+ if (hFont == NULL) {
+ return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily);
+ }
+ } else {
+ if (Charset == FXFONT_SYMBOL_CHARSET) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ || _FXM_PLATFORM_ == _FXM_PLATFORM_ANDROID_
+ if (SubstName == FX_BSTRC("Symbol")) {
+ pSubstFont->m_Family = "Chrome Symbol";
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
+ pSubstFont->m_Charset = FXFONT_SYMBOL_CHARSET;
+ if (m_FoxitFaces[12]) {
+ return m_FoxitFaces[12];
+ }
+ FX_LPCBYTE pFontData = NULL;
+ FX_DWORD size = 0;
+ m_pFontMgr->GetStandardFont(pFontData, size, 12);
+ m_FoxitFaces[12] = m_pFontMgr->GetFixedFace(pFontData, size, 0);
+ return m_FoxitFaces[12];
+ } else {
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL;
+ return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, weight, italic_angle, 0, pSubstFont);
+ }
+#else
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_NONSYMBOL;
+ return FindSubstFont(family, bTrueType, flags & ~FXFONT_SYMBOLIC, weight, italic_angle, 0, pSubstFont);
+#endif
+ }
+ if (Charset == FXFONT_ANSI_CHARSET) {
+ pSubstFont->m_SubstFlags |= FXFONT_SUBST_STANDARD;
+ return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily);
+ }
+ int index = m_CharsetArray.Find(Charset);
+ if (index < 0) {
+ return UseInternalSubst(pSubstFont, iBaseFont, italic_angle, old_weight, PitchFamily);
+ } else {
+ hFont = m_pFontInfo->GetFont(m_FaceArray[index]);
+ }
+ }
+ }
+ pSubstFont->m_ExtHandle = m_pFontInfo->RetainFont(hFont);
+ if (hFont == NULL) {
+ return NULL;
+ }
+ m_pFontInfo->GetFaceName(hFont, SubstName);
+ if (Charset == FXFONT_DEFAULT_CHARSET) {
+ m_pFontInfo->GetFontCharset(hFont, Charset);
+ }
+ FX_DWORD ttc_size = m_pFontInfo->GetFontData(hFont, 0x74746366, NULL, 0);
+ FX_DWORD font_size = m_pFontInfo->GetFontData(hFont, 0, NULL, 0);
+ if(font_size == 0 && ttc_size == 0) {
+ m_pFontInfo->DeleteFont(hFont);
+ return NULL;
+ }
+ FXFT_Face face = NULL;
+ if (ttc_size) {
+ FX_BYTE temp[1024];
+ m_pFontInfo->GetFontData(hFont, 0x74746366, temp, 1024);
+ FX_DWORD checksum = 0;
+ for (int i = 0; i < 256; i ++) {
+ checksum += ((FX_DWORD*)temp)[i];
+ }
+ FX_LPBYTE pFontData;
+ face = m_pFontMgr->GetCachedTTCFace(ttc_size, checksum, ttc_size - font_size, pFontData);
+ if (face == NULL) {
+ pFontData = FX_Alloc(FX_BYTE, ttc_size);
+ if (pFontData) {
+ m_pFontInfo->GetFontData(hFont, 0x74746366, pFontData, ttc_size);
+ face = m_pFontMgr->AddCachedTTCFace(ttc_size, checksum, pFontData, ttc_size,
+ ttc_size - font_size);
+ }
+ }
+ } else {
+ FX_LPBYTE pFontData;
+ face = m_pFontMgr->GetCachedFace(SubstName, weight, bItalic, pFontData);
+ if (face == NULL) {
+ pFontData = FX_Alloc(FX_BYTE, font_size);
+ if (!pFontData) {
+ m_pFontInfo->DeleteFont(hFont);
+ return NULL;
+ }
+ m_pFontInfo->GetFontData(hFont, 0, pFontData, font_size);
+ face = m_pFontMgr->AddCachedFace(SubstName, weight, bItalic, pFontData, font_size, m_pFontInfo->GetFaceIndex(hFont));
+ }
+ }
+ if (face == NULL) {
+ m_pFontInfo->DeleteFont(hFont);
+ return NULL;
+ }
+ pSubstFont->m_Family = SubstName;
+ pSubstFont->m_Charset = Charset;
+ FX_BOOL bNeedUpdateWeight = FALSE;
+ if (FXFT_Is_Face_Bold(face)) {
+ if (weight == FXFONT_FW_BOLD) {
+ bNeedUpdateWeight = FALSE;
+ } else {
+ bNeedUpdateWeight = TRUE;
+ }
+ } else {
+ if (weight == FXFONT_FW_NORMAL) {
+ bNeedUpdateWeight = FALSE;
+ } else {
+ bNeedUpdateWeight = TRUE;
+ }
+ }
+ if (bNeedUpdateWeight) {
+ pSubstFont->m_Weight = weight;
+ }
+ if (bItalic && !FXFT_Is_Face_Italic(face)) {
+ if (italic_angle == 0) {
+ italic_angle = -12;
+ } else if (FXSYS_abs(italic_angle) < 5) {
+ italic_angle = 0;
+ }
+ pSubstFont->m_ItalicAngle = italic_angle;
+ }
+ m_pFontInfo->DeleteFont(hFont);
+ return face;
+}
+extern "C" {
+ unsigned long _FTStreamRead(FXFT_Stream stream, unsigned long offset,
+ unsigned char* buffer, unsigned long count);
+ void _FTStreamClose(FXFT_Stream stream);
+};
+CFontFileFaceInfo::CFontFileFaceInfo()
+{
+ m_pFile = NULL;
+ m_Face = NULL;
+ m_Charsets = 0;
+ m_FileSize = 0;
+ m_FontOffset = 0;
+ m_Weight = 0;
+ m_bItalic = FALSE;
+ m_PitchFamily = 0;
+}
+CFontFileFaceInfo::~CFontFileFaceInfo()
+{
+ if (m_Face) {
+ FXFT_Done_Face(m_Face);
+ }
+ m_Face = NULL;
+}
+extern FX_BOOL _LoadFile(FXFT_Library library, FXFT_Face* Face, IFX_FileRead* pFile, FXFT_Stream* stream);
+#if defined(_FPDFAPI_MINI_) || _FX_OS_ == _FX_ANDROID_
+IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
+{
+ return NULL;
+}
+#endif
+#if !defined(_FPDFAPI_MINI_)
+CFX_FolderFontInfo::CFX_FolderFontInfo()
+{
+}
+CFX_FolderFontInfo::~CFX_FolderFontInfo()
+{
+ FX_POSITION pos = m_FontList.GetStartPosition();
+ while (pos) {
+ CFX_ByteString key;
+ FX_LPVOID value;
+ m_FontList.GetNextAssoc(pos, key, value);
+ delete (CFontFaceInfo*)value;
+ }
+}
+void CFX_FolderFontInfo::AddPath(FX_BSTR path)
+{
+ m_PathList.Add(path);
+}
+void CFX_FolderFontInfo::Release()
+{
+ delete this;
+}
+FX_BOOL CFX_FolderFontInfo::EnumFontList(CFX_FontMapper* pMapper)
+{
+ m_pMapper = pMapper;
+ for (int i = 0; i < m_PathList.GetSize(); i ++) {
+ ScanPath(m_PathList[i]);
+ }
+ return TRUE;
+}
+void CFX_FolderFontInfo::ScanPath(CFX_ByteString& path)
+{
+ void* handle = FX_OpenFolder(path);
+ if (handle == NULL) {
+ return;
+ }
+ CFX_ByteString filename;
+ FX_BOOL bFolder;
+ while (FX_GetNextFile(handle, filename, bFolder)) {
+ if (bFolder) {
+ if (filename == "." || filename == "..") {
+ continue;
+ }
+ } else {
+ CFX_ByteString ext = filename.Right(4);
+ ext.MakeUpper();
+ if (ext != ".TTF" && ext != ".OTF" && ext != ".TTC") {
+ continue;
+ }
+ }
+ CFX_ByteString fullpath = path;
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
+ fullpath += "\\";
+#else
+ fullpath += "/";
+#endif
+ fullpath += filename;
+ if (bFolder) {
+ ScanPath(fullpath);
+ } else {
+ ScanFile(fullpath);
+ }
+ }
+ FX_CloseFolder(handle);
+}
+void CFX_FolderFontInfo::ScanFile(CFX_ByteString& path)
+{
+ FXSYS_FILE* pFile = FXSYS_fopen(path, "rb");
+ if (pFile == NULL) {
+ return;
+ }
+ FXSYS_fseek(pFile, 0, FXSYS_SEEK_END);
+ FX_DWORD filesize = FXSYS_ftell(pFile);
+ FX_BYTE buffer[16];
+ FXSYS_fseek(pFile, 0, FXSYS_SEEK_SET);
+ size_t readCnt = FXSYS_fread(buffer, 12, 1, pFile);
+ if (GET_TT_LONG(buffer) == 0x74746366) {
+ FX_DWORD nFaces = GET_TT_LONG(buffer + 8);
+ FX_LPBYTE offsets = FX_Alloc(FX_BYTE, nFaces * 4);
+ if (!offsets) {
+ FXSYS_fclose(pFile);
+ return;
+ }
+ readCnt = FXSYS_fread(offsets, nFaces * 4, 1, pFile);
+ for (FX_DWORD i = 0; i < nFaces; i ++) {
+ FX_LPBYTE p = offsets + i * 4;
+ ReportFace(path, pFile, filesize, GET_TT_LONG(p));
+ }
+ FX_Free(offsets);
+ } else {
+ ReportFace(path, pFile, filesize, 0);
+ }
+ FXSYS_fclose(pFile);
+}
+void CFX_FolderFontInfo::ReportFace(CFX_ByteString& path, FXSYS_FILE* pFile, FX_DWORD filesize, FX_DWORD offset)
+{
+ FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
+ char buffer[16];
+ if (!FXSYS_fread(buffer, 12, 1, pFile)) {
+ return;
+ }
+ FX_DWORD nTables = GET_TT_SHORT(buffer + 4);
+ CFX_ByteString tables = _FPDF_ReadStringFromFile(pFile, nTables * 16);
+ CFX_ByteString names = _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x6e616d65);
+ CFX_ByteString facename = _FPDF_GetNameFromTT(names, 1);
+ CFX_ByteString style = _FPDF_GetNameFromTT(names, 2);
+ if (style != "Regular") {
+ facename += " " + style;
+ }
+ FX_LPVOID p;
+ if (m_FontList.Lookup(facename, p)) {
+ return;
+ }
+ CFontFaceInfo* pInfo = FX_NEW CFontFaceInfo;
+ if (!pInfo) {
+ return;
+ }
+ pInfo->m_FilePath = path;
+ pInfo->m_FaceName = facename;
+ pInfo->m_FontTables = tables;
+ pInfo->m_FontOffset = offset;
+ pInfo->m_FileSize = filesize;
+ pInfo->m_Charsets = 0;
+ CFX_ByteString os2 = _FPDF_LoadTableFromTT(pFile, tables, nTables, 0x4f532f32);
+ if (os2.GetLength() >= 86) {
+ FX_LPCBYTE p = (FX_LPCBYTE)os2 + 78;
+ FX_DWORD codepages = GET_TT_LONG(p);
+ if (codepages & (1 << 17)) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_SHIFTJIS_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_SHIFTJIS;
+ }
+ if (codepages & (1 << 18)) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_GB2312_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_GB;
+ }
+ if (codepages & (1 << 20)) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_CHINESEBIG5_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_BIG5;
+ }
+ if ((codepages & (1 << 19)) || (codepages & (1 << 21))) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_HANGEUL_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_KOREAN;
+ }
+ if (codepages & (1 << 31)) {
+ m_pMapper->AddInstalledFont(facename, FXFONT_SYMBOL_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_SYMBOL;
+ }
+ }
+ m_pMapper->AddInstalledFont(facename, FXFONT_ANSI_CHARSET);
+ pInfo->m_Charsets |= CHARSET_FLAG_ANSI;
+ pInfo->m_Styles = 0;
+ if (style.Find(FX_BSTRC("Bold")) > -1) {
+ pInfo->m_Styles |= FXFONT_BOLD;
+ }
+ if (style.Find(FX_BSTRC("Italic")) > -1 || style.Find(FX_BSTRC("Oblique")) > -1) {
+ pInfo->m_Styles |= FXFONT_ITALIC;
+ }
+ if (facename.Find(FX_BSTRC("Serif")) > -1) {
+ pInfo->m_Styles |= FXFONT_SERIF;
+ }
+ m_FontList.SetAt(facename, pInfo);
+}
+void* CFX_FolderFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL& bExact)
+{
+ return NULL;
+}
+void* CFX_FolderFontInfo::GetFont(FX_LPCSTR face)
+{
+ FX_LPVOID p;
+ if (!m_FontList.Lookup(face, p)) {
+ return NULL;
+ }
+ return p;
+}
+FX_DWORD CFX_FolderFontInfo::GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size)
+{
+ if (hFont == NULL) {
+ return 0;
+ }
+ CFontFaceInfo* pFont = (CFontFaceInfo*)hFont;
+ FXSYS_FILE* pFile = NULL;
+ if (size > 0) {
+ pFile = FXSYS_fopen(pFont->m_FilePath, "rb");
+ if (pFile == NULL) {
+ return 0;
+ }
+ }
+ FX_DWORD datasize = 0;
+ FX_DWORD offset;
+ if (table == 0) {
+ datasize = pFont->m_FontOffset ? 0 : pFont->m_FileSize;
+ offset = 0;
+ } else if (table == 0x74746366) {
+ datasize = pFont->m_FontOffset ? pFont->m_FileSize : 0;
+ offset = 0;
+ } else {
+ FX_DWORD nTables = pFont->m_FontTables.GetLength() / 16;
+ for (FX_DWORD i = 0; i < nTables; i ++) {
+ FX_LPCBYTE p = (FX_LPCBYTE)pFont->m_FontTables + i * 16;
+ if (GET_TT_LONG(p) == table) {
+ offset = GET_TT_LONG(p + 8);
+ datasize = GET_TT_LONG(p + 12);
+ }
+ }
+ }
+ if (datasize && size >= datasize && pFile) {
+ FXSYS_fseek(pFile, offset, FXSYS_SEEK_SET);
+ size_t readCnt = FXSYS_fread(buffer, datasize, 1, pFile);
+ }
+ if (pFile) {
+ FXSYS_fclose(pFile);
+ }
+ return datasize;
+}
+void CFX_FolderFontInfo::DeleteFont(void* hFont)
+{
+}
+FX_BOOL CFX_FolderFontInfo::GetFaceName(void* hFont, CFX_ByteString& name)
+{
+ if (hFont == NULL) {
+ return FALSE;
+ }
+ CFontFaceInfo* pFont = (CFontFaceInfo*)hFont;
+ name = pFont->m_FaceName;
+ return TRUE;
+}
+FX_BOOL CFX_FolderFontInfo::GetFontCharset(void* hFont, int& charset)
+{
+ return FALSE;
+}
+#endif
diff --git a/core/src/fxge/ge/fx_ge_linux.cpp b/core/src/fxge/ge/fx_ge_linux.cpp
index 33cfcfe722..735ecac0c8 100644
--- a/core/src/fxge/ge/fx_ge_linux.cpp
+++ b/core/src/fxge/ge/fx_ge_linux.cpp
@@ -1,259 +1,259 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#include "../agg/include/fx_agg_driver.h"
-#include "text_int.h"
-#if !defined(_FPDFAPI_MINI_) && _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
-#if (_FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && (!defined(_FPDFAPI_MINI_)))
-void CFX_AggDeviceDriver::InitPlatform()
-{
-}
-void CFX_AggDeviceDriver::DestroyPlatform()
-{
-}
-void CFX_FaceCache::InitPlatform()
-{
-}
-FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
- CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device,
- FX_FLOAT font_size, FX_DWORD argb)
-{
- return FALSE;
-}
-CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font* pFont, FX_DWORD glyph_index, const CFX_AffineMatrix* pMatrix,
- int dest_width, int anti_alias)
-{
- return NULL;
-}
-void CFX_Font::ReleasePlatformResource()
-{
-}
-#endif
-static const struct {
- FX_LPCSTR m_pName;
- FX_LPCSTR m_pSubstName;
-}
-Base14Substs[] = {
- {"Courier", "Courier New"},
- {"Courier-Bold", "Courier New Bold"},
- {"Courier-BoldOblique", "Courier New Bold Italic"},
- {"Courier-Oblique", "Courier New Italic"},
- {"Helvetica", "Arial"},
- {"Helvetica-Bold", "Arial Bold"},
- {"Helvetica-BoldOblique", "Arial Bold Italic"},
- {"Helvetica-Oblique", "Arial Italic"},
- {"Times-Roman", "Times New Roman"},
- {"Times-Bold", "Times New Roman Bold"},
- {"Times-BoldItalic", "Times New Roman Bold Italic"},
- {"Times-Italic", "Times New Roman Italic"},
-};
-class CFX_LinuxFontInfo : public CFX_FolderFontInfo
-{
-public:
- virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL& bExact);
- FX_BOOL ParseFontCfg();
- void* FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL bMatchName);
-};
-#define LINUX_GPNAMESIZE 6
-static const struct {
- FX_LPCSTR NameArr[LINUX_GPNAMESIZE];
-}
-LinuxGpFontList[] = {
- {{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic", "VL Gothic regular"}},
- {{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL, "VL Gothic regular"}},
- {{"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}},
- {{"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}},
-};
-static const FX_LPCSTR g_LinuxGbFontList[] = {
- "AR PL UMing CN Light",
- "WenQuanYi Micro Hei",
- "AR PL UKai CN",
-};
-static const FX_LPCSTR g_LinuxB5FontList[] = {
- "AR PL UMing TW Light",
- "WenQuanYi Micro Hei",
- "AR PL UKai TW",
-};
-static const FX_LPCSTR g_LinuxHGFontList[] = {
- "UnDotum",
-};
-static FX_INT32 GetJapanesePreference(FX_LPCSTR facearr, int weight, int picth_family)
-{
- CFX_ByteString face = facearr;
- if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
- if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
- return 0;
- } else {
- return 1;
- }
- } else if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
- if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) {
- return 2;
- } else {
- return 3;
- }
- }
- if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) {
- return 0;
- }
- return 2;
-}
-void* CFX_LinuxFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact)
-{
- CFX_ByteString face = cstr_face;
- int iBaseFont;
- for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++)
- if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) {
- face = Base14Substs[iBaseFont].m_pSubstName;
- bExact = TRUE;
- break;
- }
- if (iBaseFont < 12) {
- return GetFont(face);
- }
- FX_LPVOID p = NULL;
- FX_BOOL bCJK = TRUE;
- switch (charset) {
- case FXFONT_SHIFTJIS_CHARSET: {
- FX_INT32 index = GetJapanesePreference(cstr_face, weight, pitch_family);
- if (index < 0) {
- break;
- }
- for (FX_INT32 i = 0; i < LINUX_GPNAMESIZE; i++)
- if (m_FontList.Lookup(LinuxGpFontList[index].NameArr[i], p)) {
- return p;
- }
- }
- break;
- case FXFONT_GB2312_CHARSET: {
- static FX_INT32 s_gbCount = sizeof(g_LinuxGbFontList) / sizeof(FX_LPCSTR);
- for (FX_INT32 i = 0; i < s_gbCount; i++)
- if (m_FontList.Lookup(g_LinuxGbFontList[i], p)) {
- return p;
- }
- }
- break;
- case FXFONT_CHINESEBIG5_CHARSET: {
- static FX_INT32 s_b5Count = sizeof(g_LinuxB5FontList) / sizeof(FX_LPCSTR);
- for (FX_INT32 i = 0; i < s_b5Count; i++)
- if (m_FontList.Lookup(g_LinuxB5FontList[i], p)) {
- return p;
- }
- }
- break;
- case FXFONT_HANGEUL_CHARSET: {
- static FX_INT32 s_hgCount = sizeof(g_LinuxHGFontList) / sizeof(FX_LPCSTR);
- for (FX_INT32 i = 0; i < s_hgCount; i++)
- if (m_FontList.Lookup(g_LinuxHGFontList[i], p)) {
- return p;
- }
- }
- break;
- default:
- bCJK = FALSE;
- break;
- }
- if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) {
- return GetFont("Courier New");
- }
- return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK);
-}
-static FX_DWORD _LinuxGetCharset(int charset)
-{
- switch(charset) {
- case FXFONT_SHIFTJIS_CHARSET:
- return CHARSET_FLAG_SHIFTJIS;
- case FXFONT_GB2312_CHARSET:
- return CHARSET_FLAG_GB;
- case FXFONT_CHINESEBIG5_CHARSET:
- return CHARSET_FLAG_BIG5;
- case FXFONT_HANGEUL_CHARSET:
- return CHARSET_FLAG_KOREAN;
- case FXFONT_SYMBOL_CHARSET:
- return CHARSET_FLAG_SYMBOL;
- case FXFONT_ANSI_CHARSET:
- return CHARSET_FLAG_ANSI;
- default:
- break;
- }
- return 0;
-}
-static FX_INT32 _LinuxGetSimilarValue(int weight, FX_BOOL bItalic, int pitch_family, FX_DWORD style)
-{
- FX_INT32 iSimilarValue = 0;
- if ((style & FXFONT_BOLD) == (weight > 400)) {
- iSimilarValue += 16;
- }
- if ((style & FXFONT_ITALIC) == bItalic) {
- iSimilarValue += 16;
- }
- if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) {
- iSimilarValue += 16;
- }
- if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) {
- iSimilarValue += 8;
- }
- if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) {
- iSimilarValue += 8;
- }
- return iSimilarValue;
-}
-void* CFX_LinuxFontInfo::FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL bMatchName)
-{
- CFontFaceInfo* pFind = NULL;
- FX_DWORD charset_flag = _LinuxGetCharset(charset);
- FX_INT32 iBestSimilar = 0;
- FX_POSITION pos = m_FontList.GetStartPosition();
- while (pos) {
- CFX_ByteString bsName;
- CFontFaceInfo* pFont = NULL;
- m_FontList.GetNextAssoc(pos, bsName, (FX_LPVOID&)pFont);
- if (!(pFont->m_Charsets & charset_flag) && charset != FXFONT_DEFAULT_CHARSET) {
- continue;
- }
- FX_INT32 iSimilarValue = 0;
- FX_INT32 index = bsName.Find(family);
- if (bMatchName && index < 0) {
- continue;
- }
- if (!bMatchName && index > 0) {
- iSimilarValue += 64;
- }
- iSimilarValue = _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles);
- if (iSimilarValue > iBestSimilar) {
- iBestSimilar = iSimilarValue;
- pFind = pFont;
- }
- }
- return pFind;
-}
-IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
-{
- CFX_LinuxFontInfo* pInfo = FX_NEW CFX_LinuxFontInfo;
- if (!pInfo) {
- return NULL;
- }
- if (!pInfo->ParseFontCfg()) {
- pInfo->AddPath("/usr/share/fonts");
- pInfo->AddPath("/usr/share/X11/fonts/Type1");
- pInfo->AddPath("/usr/share/X11/fonts/TTF");
- pInfo->AddPath("/usr/local/share/fonts");
- }
- return pInfo;
-}
-FX_BOOL CFX_LinuxFontInfo::ParseFontCfg()
-{
- return FALSE;
-}
-void CFX_GEModule::InitPlatform()
-{
- m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
-}
-void CFX_GEModule::DestroyPlatform()
-{
-}
-#endif
+// 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 "../../../include/fxge/fx_ge.h"
+#include "../agg/include/fx_agg_driver.h"
+#include "text_int.h"
+#if !defined(_FPDFAPI_MINI_) && _FXM_PLATFORM_ == _FXM_PLATFORM_LINUX_
+#if (_FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ && (!defined(_FPDFAPI_MINI_)))
+void CFX_AggDeviceDriver::InitPlatform()
+{
+}
+void CFX_AggDeviceDriver::DestroyPlatform()
+{
+}
+void CFX_FaceCache::InitPlatform()
+{
+}
+FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
+ CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device,
+ FX_FLOAT font_size, FX_DWORD argb)
+{
+ return FALSE;
+}
+CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph_Nativetext(CFX_Font* pFont, FX_DWORD glyph_index, const CFX_AffineMatrix* pMatrix,
+ int dest_width, int anti_alias)
+{
+ return NULL;
+}
+void CFX_Font::ReleasePlatformResource()
+{
+}
+#endif
+static const struct {
+ FX_LPCSTR m_pName;
+ FX_LPCSTR m_pSubstName;
+}
+Base14Substs[] = {
+ {"Courier", "Courier New"},
+ {"Courier-Bold", "Courier New Bold"},
+ {"Courier-BoldOblique", "Courier New Bold Italic"},
+ {"Courier-Oblique", "Courier New Italic"},
+ {"Helvetica", "Arial"},
+ {"Helvetica-Bold", "Arial Bold"},
+ {"Helvetica-BoldOblique", "Arial Bold Italic"},
+ {"Helvetica-Oblique", "Arial Italic"},
+ {"Times-Roman", "Times New Roman"},
+ {"Times-Bold", "Times New Roman Bold"},
+ {"Times-BoldItalic", "Times New Roman Bold Italic"},
+ {"Times-Italic", "Times New Roman Italic"},
+};
+class CFX_LinuxFontInfo : public CFX_FolderFontInfo
+{
+public:
+ virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL& bExact);
+ FX_BOOL ParseFontCfg();
+ void* FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL bMatchName);
+};
+#define LINUX_GPNAMESIZE 6
+static const struct {
+ FX_LPCSTR NameArr[LINUX_GPNAMESIZE];
+}
+LinuxGpFontList[] = {
+ {{"TakaoPGothic", "VL PGothic", "IPAPGothic", "VL Gothic", "Kochi Gothic", "VL Gothic regular"}},
+ {{"TakaoGothic", "VL Gothic", "IPAGothic", "Kochi Gothic", NULL, "VL Gothic regular"}},
+ {{"TakaoPMincho", "IPAPMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}},
+ {{"TakaoMincho", "IPAMincho", "VL Gothic", "Kochi Mincho", NULL, "VL Gothic regular"}},
+};
+static const FX_LPCSTR g_LinuxGbFontList[] = {
+ "AR PL UMing CN Light",
+ "WenQuanYi Micro Hei",
+ "AR PL UKai CN",
+};
+static const FX_LPCSTR g_LinuxB5FontList[] = {
+ "AR PL UMing TW Light",
+ "WenQuanYi Micro Hei",
+ "AR PL UKai TW",
+};
+static const FX_LPCSTR g_LinuxHGFontList[] = {
+ "UnDotum",
+};
+static FX_INT32 GetJapanesePreference(FX_LPCSTR facearr, int weight, int picth_family)
+{
+ CFX_ByteString face = facearr;
+ if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
+ if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
+ if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) {
+ return 2;
+ } else {
+ return 3;
+ }
+ }
+ if (!(picth_family & FXFONT_FF_ROMAN) && weight > 400) {
+ return 0;
+ }
+ return 2;
+}
+void* CFX_LinuxFontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact)
+{
+ CFX_ByteString face = cstr_face;
+ int iBaseFont;
+ for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++)
+ if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) {
+ face = Base14Substs[iBaseFont].m_pSubstName;
+ bExact = TRUE;
+ break;
+ }
+ if (iBaseFont < 12) {
+ return GetFont(face);
+ }
+ FX_LPVOID p = NULL;
+ FX_BOOL bCJK = TRUE;
+ switch (charset) {
+ case FXFONT_SHIFTJIS_CHARSET: {
+ FX_INT32 index = GetJapanesePreference(cstr_face, weight, pitch_family);
+ if (index < 0) {
+ break;
+ }
+ for (FX_INT32 i = 0; i < LINUX_GPNAMESIZE; i++)
+ if (m_FontList.Lookup(LinuxGpFontList[index].NameArr[i], p)) {
+ return p;
+ }
+ }
+ break;
+ case FXFONT_GB2312_CHARSET: {
+ static FX_INT32 s_gbCount = sizeof(g_LinuxGbFontList) / sizeof(FX_LPCSTR);
+ for (FX_INT32 i = 0; i < s_gbCount; i++)
+ if (m_FontList.Lookup(g_LinuxGbFontList[i], p)) {
+ return p;
+ }
+ }
+ break;
+ case FXFONT_CHINESEBIG5_CHARSET: {
+ static FX_INT32 s_b5Count = sizeof(g_LinuxB5FontList) / sizeof(FX_LPCSTR);
+ for (FX_INT32 i = 0; i < s_b5Count; i++)
+ if (m_FontList.Lookup(g_LinuxB5FontList[i], p)) {
+ return p;
+ }
+ }
+ break;
+ case FXFONT_HANGEUL_CHARSET: {
+ static FX_INT32 s_hgCount = sizeof(g_LinuxHGFontList) / sizeof(FX_LPCSTR);
+ for (FX_INT32 i = 0; i < s_hgCount; i++)
+ if (m_FontList.Lookup(g_LinuxHGFontList[i], p)) {
+ return p;
+ }
+ }
+ break;
+ default:
+ bCJK = FALSE;
+ break;
+ }
+ if (charset == FXFONT_ANSI_CHARSET && (pitch_family & FXFONT_FF_FIXEDPITCH)) {
+ return GetFont("Courier New");
+ }
+ return FindFont(weight, bItalic, charset, pitch_family, cstr_face, !bCJK);
+}
+static FX_DWORD _LinuxGetCharset(int charset)
+{
+ switch(charset) {
+ case FXFONT_SHIFTJIS_CHARSET:
+ return CHARSET_FLAG_SHIFTJIS;
+ case FXFONT_GB2312_CHARSET:
+ return CHARSET_FLAG_GB;
+ case FXFONT_CHINESEBIG5_CHARSET:
+ return CHARSET_FLAG_BIG5;
+ case FXFONT_HANGEUL_CHARSET:
+ return CHARSET_FLAG_KOREAN;
+ case FXFONT_SYMBOL_CHARSET:
+ return CHARSET_FLAG_SYMBOL;
+ case FXFONT_ANSI_CHARSET:
+ return CHARSET_FLAG_ANSI;
+ default:
+ break;
+ }
+ return 0;
+}
+static FX_INT32 _LinuxGetSimilarValue(int weight, FX_BOOL bItalic, int pitch_family, FX_DWORD style)
+{
+ FX_INT32 iSimilarValue = 0;
+ if ((style & FXFONT_BOLD) == (weight > 400)) {
+ iSimilarValue += 16;
+ }
+ if ((style & FXFONT_ITALIC) == bItalic) {
+ iSimilarValue += 16;
+ }
+ if ((style & FXFONT_SERIF) == (pitch_family & FXFONT_FF_ROMAN)) {
+ iSimilarValue += 16;
+ }
+ if ((style & FXFONT_SCRIPT) == (pitch_family & FXFONT_FF_SCRIPT)) {
+ iSimilarValue += 8;
+ }
+ if ((style & FXFONT_FIXED_PITCH) == (pitch_family & FXFONT_FF_FIXEDPITCH)) {
+ iSimilarValue += 8;
+ }
+ return iSimilarValue;
+}
+void* CFX_LinuxFontInfo::FindFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR family, FX_BOOL bMatchName)
+{
+ CFontFaceInfo* pFind = NULL;
+ FX_DWORD charset_flag = _LinuxGetCharset(charset);
+ FX_INT32 iBestSimilar = 0;
+ FX_POSITION pos = m_FontList.GetStartPosition();
+ while (pos) {
+ CFX_ByteString bsName;
+ CFontFaceInfo* pFont = NULL;
+ m_FontList.GetNextAssoc(pos, bsName, (FX_LPVOID&)pFont);
+ if (!(pFont->m_Charsets & charset_flag) && charset != FXFONT_DEFAULT_CHARSET) {
+ continue;
+ }
+ FX_INT32 iSimilarValue = 0;
+ FX_INT32 index = bsName.Find(family);
+ if (bMatchName && index < 0) {
+ continue;
+ }
+ if (!bMatchName && index > 0) {
+ iSimilarValue += 64;
+ }
+ iSimilarValue = _LinuxGetSimilarValue(weight, bItalic, pitch_family, pFont->m_Styles);
+ if (iSimilarValue > iBestSimilar) {
+ iBestSimilar = iSimilarValue;
+ pFind = pFont;
+ }
+ }
+ return pFind;
+}
+IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
+{
+ CFX_LinuxFontInfo* pInfo = FX_NEW CFX_LinuxFontInfo;
+ if (!pInfo) {
+ return NULL;
+ }
+ if (!pInfo->ParseFontCfg()) {
+ pInfo->AddPath("/usr/share/fonts");
+ pInfo->AddPath("/usr/share/X11/fonts/Type1");
+ pInfo->AddPath("/usr/share/X11/fonts/TTF");
+ pInfo->AddPath("/usr/local/share/fonts");
+ }
+ return pInfo;
+}
+FX_BOOL CFX_LinuxFontInfo::ParseFontCfg()
+{
+ return FALSE;
+}
+void CFX_GEModule::InitPlatform()
+{
+ m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
+}
+void CFX_GEModule::DestroyPlatform()
+{
+}
+#endif
diff --git a/core/src/fxge/ge/fx_ge_path.cpp b/core/src/fxge/ge/fx_ge_path.cpp
index fc6ee52f1f..cd3ff0efbe 100644
--- a/core/src/fxge/ge/fx_ge_path.cpp
+++ b/core/src/fxge/ge/fx_ge_path.cpp
@@ -1,654 +1,654 @@
-// 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 "../../../include/fxcrt/fx_basic.h"
-#include "../../../include/fxge/fx_ge.h"
-CFX_ClipRgn::CFX_ClipRgn(int width, int height)
-{
- m_Type = RectI;
- m_Box.left = m_Box.top = 0;
- m_Box.right = width;
- m_Box.bottom = height;
-}
-CFX_ClipRgn::CFX_ClipRgn(const FX_RECT& rect)
-{
- m_Type = RectI;
- m_Box = rect;
-}
-CFX_ClipRgn::CFX_ClipRgn(const CFX_ClipRgn& src)
-{
- m_Type = src.m_Type;
- m_Box = src.m_Box;
- m_Mask = src.m_Mask;
-}
-CFX_ClipRgn::~CFX_ClipRgn()
-{
-}
-void CFX_ClipRgn::Reset(const FX_RECT& rect)
-{
- m_Type = RectI;
- m_Box = rect;
- m_Mask.SetNull();
-}
-void CFX_ClipRgn::IntersectRect(const FX_RECT& rect)
-{
- if (m_Type == RectI) {
- m_Box.Intersect(rect);
- return;
- }
- if (m_Type == MaskF) {
- IntersectMaskRect(rect, m_Box, m_Mask);
- return;
- }
-}
-void CFX_ClipRgn::IntersectMaskRect(FX_RECT rect, FX_RECT mask_rect, CFX_DIBitmapRef Mask)
-{
- const CFX_DIBitmap* mask_dib = Mask;
- m_Type = MaskF;
- m_Box = rect;
- m_Box.Intersect(mask_rect);
- if (m_Box.IsEmpty()) {
- m_Type = RectI;
- return;
- } else if (m_Box == mask_rect) {
- m_Mask = Mask;
- return;
- }
- CFX_DIBitmap* new_dib = m_Mask.New();
- if (!new_dib) {
- return;
- }
- new_dib->Create(m_Box.Width(), m_Box.Height(), FXDIB_8bppMask);
- for (int row = m_Box.top; row < m_Box.bottom; row ++) {
- FX_LPBYTE dest_scan = new_dib->GetBuffer() + new_dib->GetPitch() * (row - m_Box.top);
- FX_LPBYTE src_scan = mask_dib->GetBuffer() + mask_dib->GetPitch() * (row - mask_rect.top);
- for (int col = m_Box.left; col < m_Box.right; col ++) {
- dest_scan[col - m_Box.left] = src_scan[col - mask_rect.left];
- }
- }
-}
-void CFX_ClipRgn::IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask)
-{
- const CFX_DIBitmap* mask_dib = Mask;
- ASSERT(mask_dib->GetFormat() == FXDIB_8bppMask);
- FX_RECT mask_box(left, top, left + mask_dib->GetWidth(), top + mask_dib->GetHeight());
- if (m_Type == RectI) {
- IntersectMaskRect(m_Box, mask_box, Mask);
- return;
- }
- if (m_Type == MaskF) {
- FX_RECT new_box = m_Box;
- new_box.Intersect(mask_box);
- if (new_box.IsEmpty()) {
- m_Type = RectI;
- m_Mask.SetNull();
- m_Box = new_box;
- return;
- }
- CFX_DIBitmapRef new_mask;
- CFX_DIBitmap* new_dib = new_mask.New();
- if (!new_dib) {
- return;
- }
- new_dib->Create(new_box.Width(), new_box.Height(), FXDIB_8bppMask);
- const CFX_DIBitmap* old_dib = m_Mask;
- for (int row = new_box.top; row < new_box.bottom; row ++) {
- FX_LPBYTE old_scan = old_dib->GetBuffer() + (row - m_Box.top) * old_dib->GetPitch();
- FX_LPBYTE mask_scan = mask_dib->GetBuffer() + (row - top) * mask_dib->GetPitch();
- FX_LPBYTE new_scan = new_dib->GetBuffer() + (row - new_box.top) * new_dib->GetPitch();
- for (int col = new_box.left; col < new_box.right; col ++) {
- new_scan[col - new_box.left] = old_scan[col - m_Box.left] * mask_scan[col - left] / 255;
- }
- }
- m_Box = new_box;
- m_Mask = new_mask;
- return;
- }
- ASSERT(FALSE);
-}
-CFX_PathData::CFX_PathData()
-{
- m_PointCount = m_AllocCount = 0;
- m_pPoints = NULL;
-}
-CFX_PathData::~CFX_PathData()
-{
- if (m_pPoints) {
- FX_Free(m_pPoints);
- }
-}
-FX_BOOL CFX_PathData::SetPointCount(int nPoints)
-{
- m_PointCount = nPoints;
- if (m_AllocCount < nPoints) {
- if (m_pPoints) {
- FX_Free(m_pPoints);
- m_pPoints = NULL;
- }
- m_pPoints = FX_Alloc(FX_PATHPOINT, nPoints);
- if (!m_pPoints) {
- return FALSE;
- }
- m_AllocCount = nPoints;
- }
- return TRUE;
-}
-FX_BOOL CFX_PathData::AllocPointCount(int nPoints)
-{
- if (m_AllocCount < nPoints) {
- FX_PATHPOINT* pNewBuf = FX_Alloc(FX_PATHPOINT, nPoints);
- if (!pNewBuf) {
- return FALSE;
- }
- if (m_PointCount) {
- FXSYS_memcpy32(pNewBuf, m_pPoints, m_PointCount * sizeof(FX_PATHPOINT));
- }
- if (m_pPoints) {
- FX_Free(m_pPoints);
- }
- m_pPoints = pNewBuf;
- m_AllocCount = nPoints;
- }
- return TRUE;
-}
-CFX_PathData::CFX_PathData(const CFX_PathData& src)
-{
- m_pPoints = NULL;
- m_PointCount = m_AllocCount = src.m_PointCount;
- m_pPoints = FX_Alloc(FX_PATHPOINT, src.m_PointCount);
- if (!m_pPoints) {
- return;
- }
- FXSYS_memcpy32(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
-}
-void CFX_PathData::TrimPoints(int nPoints)
-{
- if (m_PointCount <= nPoints) {
- return;
- }
- SetPointCount(nPoints);
-}
-FX_BOOL CFX_PathData::AddPointCount(int addPoints)
-{
- int new_count = m_PointCount + addPoints;
- if (!AllocPointCount(new_count)) {
- return FALSE;
- }
- m_PointCount = new_count;
- return TRUE;
-}
-FX_BOOL CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_AffineMatrix* pMatrix)
-{
- int old_count = m_PointCount;
- if (!AddPointCount(pSrc->m_PointCount)) {
- return FALSE;
- }
- FXSYS_memcpy32(m_pPoints + old_count, pSrc->m_pPoints, pSrc->m_PointCount * sizeof(FX_PATHPOINT));
- if (pMatrix == NULL) {
- return TRUE;
- }
- for (int i = 0; i < pSrc->m_PointCount; i ++) {
- pMatrix->Transform(m_pPoints[old_count + i].m_PointX, m_pPoints[old_count + i].m_PointY);
- }
- return TRUE;
-}
-void CFX_PathData::SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag)
-{
- ASSERT(index < m_PointCount);
- m_pPoints[index].m_PointX = x;
- m_pPoints[index].m_PointY = y;
- m_pPoints[index].m_Flag = flag;
-}
-FX_BOOL CFX_PathData::AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top)
-{
- int old_count = m_PointCount;
- if (!AddPointCount(5)) {
- return FALSE;
- }
- FX_PATHPOINT* pPoints = m_pPoints + old_count;
- pPoints[0].m_PointX = pPoints[1].m_PointX = pPoints[4].m_PointX = left;
- pPoints[2].m_PointX = pPoints[3].m_PointX = right;
- pPoints[0].m_PointY = pPoints[3].m_PointY = pPoints[4].m_PointY = bottom;
- pPoints[1].m_PointY = pPoints[2].m_PointY = top;
- pPoints[0].m_Flag = FXPT_MOVETO;
- pPoints[1].m_Flag = pPoints[2].m_Flag = pPoints[3].m_Flag = FXPT_LINETO;
- pPoints[4].m_Flag = FXPT_LINETO | FXPT_CLOSEFIGURE;
- return TRUE;
-}
-CFX_FloatRect CFX_PathData::GetBoundingBox() const
-{
- CFX_FloatRect rect;
- if (m_PointCount) {
- rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY);
- for (int i = 1; i < m_PointCount; i ++) {
- rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
- }
- }
- return rect;
-}
-static void _UpdateLineEndPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y, FX_FLOAT end_x, FX_FLOAT end_y,
- FX_FLOAT hw)
-{
- if (start_x == end_x) {
- if (start_y == end_y) {
- rect.UpdateRect(end_x + hw, end_y + hw);
- rect.UpdateRect(end_x - hw, end_y - hw);
- return;
- }
- FX_FLOAT point_y;
- if (end_y < start_y) {
- point_y = end_y - hw;
- } else {
- point_y = end_y + hw;
- }
- rect.UpdateRect(end_x + hw, point_y);
- rect.UpdateRect(end_x - hw, point_y);
- return;
- } else if (start_y == end_y) {
- FX_FLOAT point_x;
- if (end_x < start_x) {
- point_x = end_x - hw;
- } else {
- point_x = end_x + hw;
- }
- rect.UpdateRect(point_x, end_y + hw);
- rect.UpdateRect(point_x, end_y - hw);
- return;
- }
- FX_FLOAT dx = end_x - start_x;
- FX_FLOAT dy = end_y - start_y;
- FX_FLOAT ll = FXSYS_sqrt2(dx, dy);
- FX_FLOAT mx = end_x + hw * dx / ll;
- FX_FLOAT my = end_y + hw * dy / ll;
- FX_FLOAT dx1 = hw * dy / ll;
- FX_FLOAT dy1 = hw * dx / ll;
- rect.UpdateRect(mx - dx1, my + dy1);
- rect.UpdateRect(mx + dx1, my - dy1);
-}
-static void _UpdateLineJoinPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y,
- FX_FLOAT middle_x, FX_FLOAT middle_y, FX_FLOAT end_x, FX_FLOAT end_y,
- FX_FLOAT half_width, FX_FLOAT miter_limit)
-{
- FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0, start_dc = 0, end_len = 0, end_dc = 0;
- FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20;
- FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20;
- if (bStartVert && bEndVert) {
- int start_dir = middle_y > start_y ? 1 : -1;
- FX_FLOAT point_y = middle_y + half_width * start_dir;
- rect.UpdateRect(middle_x + half_width, point_y);
- rect.UpdateRect(middle_x - half_width, point_y);
- return;
- }
- if (!bStartVert) {
- start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x);
- start_c = middle_y - FXSYS_Mul(start_k, middle_x);
- start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y);
- start_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, start_len, start_x - middle_x));
- }
- if (!bEndVert) {
- end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x);
- end_c = middle_y - FXSYS_Mul(end_k, middle_x);
- end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y);
- end_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, end_len, end_x - middle_x));
- }
- if (bStartVert) {
- FX_FLOAT outside_x = start_x;
- if (end_x < start_x) {
- outside_x += half_width;
- } else {
- outside_x -= half_width;
- }
- FX_FLOAT outside_y;
- if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
- outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc;
- } else {
- outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc;
- }
- rect.UpdateRect(outside_x, outside_y);
- return;
- }
- if (bEndVert) {
- FX_FLOAT outside_x = end_x;
- if (start_x < end_x) {
- outside_x += half_width;
- } else {
- outside_x -= half_width;
- }
- FX_FLOAT outside_y;
- if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
- outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc;
- } else {
- outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc;
- }
- rect.UpdateRect(outside_x, outside_y);
- return;
- }
- if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) {
- int start_dir = middle_x > start_x ? 1 : -1;
- int end_dir = end_x > middle_x ? 1 : -1;
- if (start_dir == end_dir) {
- _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width);
- } else {
- _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y, half_width);
- }
- return;
- }
- FX_FLOAT start_outside_c = start_c;
- if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
- start_outside_c += start_dc;
- } else {
- start_outside_c -= start_dc;
- }
- FX_FLOAT end_outside_c = end_c;
- if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
- end_outside_c += end_dc;
- } else {
- end_outside_c -= end_dc;
- }
- FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k);
- FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c;
- rect.UpdateRect(join_x, join_y);
-}
-CFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const
-{
- CFX_FloatRect rect(100000 * 1.0f, 100000 * 1.0f, -100000 * 1.0f, -100000 * 1.0f);
- int iPoint = 0;
- FX_FLOAT half_width = line_width;
- int iStartPoint, iEndPoint, iMiddlePoint;
- FX_BOOL bJoin;
- while (iPoint < m_PointCount) {
- if (m_pPoints[iPoint].m_Flag == FXPT_MOVETO) {
- iStartPoint = iPoint + 1;
- iEndPoint = iPoint;
- bJoin = FALSE;
- } else {
- if (m_pPoints[iPoint].m_Flag == FXPT_BEZIERTO) {
- rect.UpdateRect(m_pPoints[iPoint].m_PointX, m_pPoints[iPoint].m_PointY);
- rect.UpdateRect(m_pPoints[iPoint + 1].m_PointX, m_pPoints[iPoint + 1].m_PointY);
- iPoint += 2;
- }
- if (iPoint == m_PointCount - 1 || m_pPoints[iPoint + 1].m_Flag == FXPT_MOVETO) {
- iStartPoint = iPoint - 1;
- iEndPoint = iPoint;
- bJoin = FALSE;
- } else {
- iStartPoint = iPoint - 1;
- iMiddlePoint = iPoint;
- iEndPoint = iPoint + 1;
- bJoin = TRUE;
- }
- }
- FX_FLOAT start_x = m_pPoints[iStartPoint].m_PointX;
- FX_FLOAT start_y = m_pPoints[iStartPoint].m_PointY;
- FX_FLOAT end_x = m_pPoints[iEndPoint].m_PointX;
- FX_FLOAT end_y = m_pPoints[iEndPoint].m_PointY;
- if (bJoin) {
- FX_FLOAT middle_x = m_pPoints[iMiddlePoint].m_PointX;
- FX_FLOAT middle_y = m_pPoints[iMiddlePoint].m_PointY;
- _UpdateLineJoinPoints(rect, start_x, start_y, middle_x, middle_y, end_x, end_y, half_width, miter_limit);
- } else {
- _UpdateLineEndPoints(rect, start_x, start_y, end_x, end_y, half_width);
- }
- iPoint ++;
- }
- return rect;
-}
-void CFX_PathData::Transform(const CFX_AffineMatrix* pMatrix)
-{
- if (pMatrix == NULL) {
- return;
- }
- for (int i = 0; i < m_PointCount; i ++) {
- pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
- }
-}
-const int g_Distant[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
-FX_BOOL CFX_PathData::GetZeroAreaPath(CFX_PathData& NewPath, CFX_AffineMatrix* pMatrix, FX_BOOL&bThin, FX_BOOL bAdjust) const
-{
- if (m_PointCount < 3) {
- return FALSE;
- }
- if (m_PointCount == 3 && (m_pPoints[0].m_Flag & FXPT_TYPE) == FXPT_MOVETO &&
- (m_pPoints[1].m_Flag & FXPT_TYPE) == FXPT_LINETO && (m_pPoints[2].m_Flag & FXPT_TYPE) == FXPT_LINETO
- && m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) {
- NewPath.AddPointCount(2);
- if (bAdjust) {
- if (pMatrix) {
- FX_FLOAT x = m_pPoints[0].m_PointX, y = m_pPoints[0].m_PointY;
- pMatrix->TransformPoint(x, y);
- x = (int)x + 0.5f;
- y = (int)y + 0.5f;
- NewPath.SetPoint(0, x, y, FXPT_MOVETO);
- x = m_pPoints[1].m_PointX, y = m_pPoints[1].m_PointY;
- pMatrix->TransformPoint(x, y);
- x = (int)x + 0.5f;
- y = (int)y + 0.5f;
- NewPath.SetPoint(1, x, y, FXPT_LINETO);
- pMatrix->SetIdentity();
- } else {
- FX_FLOAT x = (int)m_pPoints[0].m_PointX + 0.5f, y = (int)m_pPoints[0].m_PointY + 0.5f;
- NewPath.SetPoint(0, x, y, FXPT_MOVETO);
- x = (int)m_pPoints[1].m_PointX + 0.5f, y = (int)m_pPoints[1].m_PointY + 0.5f;
- NewPath.SetPoint(1, x, y, FXPT_LINETO);
- }
- } else {
- NewPath.SetPoint(0, m_pPoints[0].m_PointX, m_pPoints[0].m_PointY, FXPT_MOVETO);
- NewPath.SetPoint(1, m_pPoints[1].m_PointX, m_pPoints[1].m_PointY, FXPT_LINETO);
- }
- if (m_pPoints[0].m_PointX != m_pPoints[1].m_PointX && m_pPoints[0].m_PointY != m_pPoints[1].m_PointY) {
- bThin = TRUE;
- }
- return TRUE;
- }
- if (((m_PointCount > 3) && (m_PointCount % 2))) {
- int mid = m_PointCount / 2;
- FX_BOOL bZeroArea = FALSE;
- CFX_PathData t_path;
- for (int i = 0; i < mid; i++) {
- if (!(m_pPoints[mid - i - 1].m_PointX == m_pPoints[mid + i + 1].m_PointX
- && m_pPoints[mid - i - 1].m_PointY == m_pPoints[mid + i + 1].m_PointY &&
- ((m_pPoints[mid - i - 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && (m_pPoints[mid + i + 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO))) {
- bZeroArea = TRUE;
- break;
- }
- int new_count = t_path.GetPointCount();
- t_path.AddPointCount(2);
- t_path.SetPoint(new_count, m_pPoints[mid - i].m_PointX, m_pPoints[mid - i].m_PointY, FXPT_MOVETO);
- t_path.SetPoint(new_count + 1, m_pPoints[mid - i - 1].m_PointX, m_pPoints[mid - i - 1].m_PointY, FXPT_LINETO);
- }
- if (!bZeroArea) {
- NewPath.Append(&t_path, NULL);
- bThin = TRUE;
- return TRUE;
- }
- }
- int stratPoint = 0;
- int next = 0, i;
- for (i = 0; i < m_PointCount; i++) {
- int point_type = m_pPoints[i].m_Flag & FXPT_TYPE;
- if (point_type == FXPT_MOVETO) {
- stratPoint = i;
- } else if (point_type == FXPT_LINETO) {
- next = (i + 1 - stratPoint) % (m_PointCount - stratPoint) + stratPoint;
- if ((m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && (m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_MOVETO) {
- if((m_pPoints[i - 1].m_PointX == m_pPoints[i].m_PointX && m_pPoints[i].m_PointX == m_pPoints[next].m_PointX)
- && ((m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) * (m_pPoints[i].m_PointY - m_pPoints[next].m_PointY) > 0)) {
- int pre = i;
- if (FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY)
- < FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[next].m_PointY)) {
- pre --;
- next--;
- }
- int new_count = NewPath.GetPointCount();
- NewPath.AddPointCount(2);
- NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoints[pre].m_PointY, FXPT_MOVETO);
- NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_pPoints[next].m_PointY, FXPT_LINETO);
- } else if((m_pPoints[i - 1].m_PointY == m_pPoints[i].m_PointY && m_pPoints[i].m_PointY == m_pPoints[next].m_PointY)
- && ((m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) * (m_pPoints[i].m_PointX - m_pPoints[next].m_PointX) > 0)) {
- int pre = i;
- if (FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX)
- < FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[next].m_PointX)) {
- pre --;
- next--;
- }
- int new_count = NewPath.GetPointCount();
- NewPath.AddPointCount(2);
- NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoints[pre].m_PointY, FXPT_MOVETO);
- NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_pPoints[next].m_PointY, FXPT_LINETO);
- } else if ((m_pPoints[i - 1].m_Flag & FXPT_TYPE) == FXPT_MOVETO && (m_pPoints[next].m_Flag & FXPT_TYPE) == FXPT_LINETO &&
- m_pPoints[i - 1].m_PointX == m_pPoints[next].m_PointX && m_pPoints[i - 1].m_PointY == m_pPoints[next].m_PointY
- && m_pPoints[next].m_Flag & FXPT_CLOSEFIGURE) {
- int new_count = NewPath.GetPointCount();
- NewPath.AddPointCount(2);
- NewPath.SetPoint(new_count, m_pPoints[i - 1].m_PointX, m_pPoints[i - 1].m_PointY, FXPT_MOVETO);
- NewPath.SetPoint(new_count + 1, m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, FXPT_LINETO);
- bThin = TRUE;
- }
- }
- } else if (point_type == FXPT_BEZIERTO) {
- i += 2;
- continue;
- }
- }
- if (m_PointCount > 3 && NewPath.GetPointCount()) {
- bThin = TRUE;
- }
- if (NewPath.GetPointCount() == 0) {
- return FALSE;
- }
- return TRUE;
-}
-FX_BOOL CFX_PathData::IsRect() const
-{
- if (m_PointCount != 5 && m_PointCount != 4) {
- return FALSE;
- }
- if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX ||
- m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
- (m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) ||
- (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
- return FALSE;
- }
- if (m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
- return FALSE;
- }
- for (int i = 1; i < 4; i ++) {
- if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) {
- return FALSE;
- }
- if (m_pPoints[i].m_PointX != m_pPoints[i - 1].m_PointX && m_pPoints[i].m_PointY != m_pPoints[i - 1].m_PointY) {
- return FALSE;
- }
- }
- return m_PointCount == 5 || (m_pPoints[3].m_Flag & FXPT_CLOSEFIGURE);
-}
-FX_BOOL CFX_PathData::IsRect(const CFX_AffineMatrix* pMatrix, CFX_FloatRect* pRect) const
-{
- if (pMatrix == NULL) {
- if (!IsRect()) {
- return FALSE;
- }
- if (pRect) {
- pRect->left = m_pPoints[0].m_PointX;
- pRect->right = m_pPoints[2].m_PointX;
- pRect->bottom = m_pPoints[0].m_PointY;
- pRect->top = m_pPoints[2].m_PointY;
- pRect->Normalize();
- }
- return TRUE;
- }
- if (m_PointCount != 5 && m_PointCount != 4) {
- return FALSE;
- }
- if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
- (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
- return FALSE;
- }
- if (m_PointCount == 4 && m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
- return FALSE;
- }
- FX_FLOAT x[5], y[5];
- for (int i = 0; i < m_PointCount; i ++) {
- pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, x[i], y[i]);
- if (i) {
- if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) {
- return FALSE;
- }
- if (x[i] != x[i - 1] && y[i] != y[i - 1]) {
- return FALSE;
- }
- }
- }
- if (pRect) {
- pRect->left = x[0];
- pRect->right = x[2];
- pRect->bottom = y[0];
- pRect->top = y[2];
- pRect->Normalize();
- }
- return TRUE;
-}
-FX_BOOL CFX_PathData::Copy(const CFX_PathData &src)
-{
- if (!SetPointCount(src.m_PointCount)) {
- return FALSE;
- }
- FXSYS_memcpy32(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
- return TRUE;
-}
-CFX_GraphStateData::CFX_GraphStateData()
-{
- m_LineCap = LineCapButt;
- m_DashCount = 0;
- m_DashArray = NULL;
- m_DashPhase = 0;
- m_LineJoin = LineJoinMiter;
- m_MiterLimit = 10 * 1.0f;
- m_LineWidth = 1.0f;
-}
-CFX_GraphStateData::CFX_GraphStateData(const CFX_GraphStateData& src)
-{
- m_DashArray = NULL;
- Copy(src);
-}
-void CFX_GraphStateData::Copy(const CFX_GraphStateData& src)
-{
- m_LineCap = src.m_LineCap;
- m_DashCount = src.m_DashCount;
- if (m_DashArray) {
- FX_Free(m_DashArray);
- }
- m_DashArray = NULL;
- m_DashPhase = src.m_DashPhase;
- m_LineJoin = src.m_LineJoin;
- m_MiterLimit = src.m_MiterLimit;
- m_LineWidth = src.m_LineWidth;
- if (m_DashCount) {
- m_DashArray = FX_Alloc(FX_FLOAT, m_DashCount);
- if (!m_DashArray) {
- return;
- }
- FXSYS_memcpy32(m_DashArray, src.m_DashArray, m_DashCount * sizeof(FX_FLOAT));
- }
-}
-CFX_GraphStateData::~CFX_GraphStateData()
-{
- if (m_DashArray) {
- FX_Free(m_DashArray);
- }
-}
-void CFX_GraphStateData::SetDashCount(int count)
-{
- if (m_DashArray) {
- FX_Free(m_DashArray);
- }
- m_DashArray = NULL;
- m_DashCount = count;
- if (count == 0) {
- return;
- }
- m_DashArray = FX_Alloc(FX_FLOAT, count);
-}
+// 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 "../../../include/fxcrt/fx_basic.h"
+#include "../../../include/fxge/fx_ge.h"
+CFX_ClipRgn::CFX_ClipRgn(int width, int height)
+{
+ m_Type = RectI;
+ m_Box.left = m_Box.top = 0;
+ m_Box.right = width;
+ m_Box.bottom = height;
+}
+CFX_ClipRgn::CFX_ClipRgn(const FX_RECT& rect)
+{
+ m_Type = RectI;
+ m_Box = rect;
+}
+CFX_ClipRgn::CFX_ClipRgn(const CFX_ClipRgn& src)
+{
+ m_Type = src.m_Type;
+ m_Box = src.m_Box;
+ m_Mask = src.m_Mask;
+}
+CFX_ClipRgn::~CFX_ClipRgn()
+{
+}
+void CFX_ClipRgn::Reset(const FX_RECT& rect)
+{
+ m_Type = RectI;
+ m_Box = rect;
+ m_Mask.SetNull();
+}
+void CFX_ClipRgn::IntersectRect(const FX_RECT& rect)
+{
+ if (m_Type == RectI) {
+ m_Box.Intersect(rect);
+ return;
+ }
+ if (m_Type == MaskF) {
+ IntersectMaskRect(rect, m_Box, m_Mask);
+ return;
+ }
+}
+void CFX_ClipRgn::IntersectMaskRect(FX_RECT rect, FX_RECT mask_rect, CFX_DIBitmapRef Mask)
+{
+ const CFX_DIBitmap* mask_dib = Mask;
+ m_Type = MaskF;
+ m_Box = rect;
+ m_Box.Intersect(mask_rect);
+ if (m_Box.IsEmpty()) {
+ m_Type = RectI;
+ return;
+ } else if (m_Box == mask_rect) {
+ m_Mask = Mask;
+ return;
+ }
+ CFX_DIBitmap* new_dib = m_Mask.New();
+ if (!new_dib) {
+ return;
+ }
+ new_dib->Create(m_Box.Width(), m_Box.Height(), FXDIB_8bppMask);
+ for (int row = m_Box.top; row < m_Box.bottom; row ++) {
+ FX_LPBYTE dest_scan = new_dib->GetBuffer() + new_dib->GetPitch() * (row - m_Box.top);
+ FX_LPBYTE src_scan = mask_dib->GetBuffer() + mask_dib->GetPitch() * (row - mask_rect.top);
+ for (int col = m_Box.left; col < m_Box.right; col ++) {
+ dest_scan[col - m_Box.left] = src_scan[col - mask_rect.left];
+ }
+ }
+}
+void CFX_ClipRgn::IntersectMaskF(int left, int top, CFX_DIBitmapRef Mask)
+{
+ const CFX_DIBitmap* mask_dib = Mask;
+ ASSERT(mask_dib->GetFormat() == FXDIB_8bppMask);
+ FX_RECT mask_box(left, top, left + mask_dib->GetWidth(), top + mask_dib->GetHeight());
+ if (m_Type == RectI) {
+ IntersectMaskRect(m_Box, mask_box, Mask);
+ return;
+ }
+ if (m_Type == MaskF) {
+ FX_RECT new_box = m_Box;
+ new_box.Intersect(mask_box);
+ if (new_box.IsEmpty()) {
+ m_Type = RectI;
+ m_Mask.SetNull();
+ m_Box = new_box;
+ return;
+ }
+ CFX_DIBitmapRef new_mask;
+ CFX_DIBitmap* new_dib = new_mask.New();
+ if (!new_dib) {
+ return;
+ }
+ new_dib->Create(new_box.Width(), new_box.Height(), FXDIB_8bppMask);
+ const CFX_DIBitmap* old_dib = m_Mask;
+ for (int row = new_box.top; row < new_box.bottom; row ++) {
+ FX_LPBYTE old_scan = old_dib->GetBuffer() + (row - m_Box.top) * old_dib->GetPitch();
+ FX_LPBYTE mask_scan = mask_dib->GetBuffer() + (row - top) * mask_dib->GetPitch();
+ FX_LPBYTE new_scan = new_dib->GetBuffer() + (row - new_box.top) * new_dib->GetPitch();
+ for (int col = new_box.left; col < new_box.right; col ++) {
+ new_scan[col - new_box.left] = old_scan[col - m_Box.left] * mask_scan[col - left] / 255;
+ }
+ }
+ m_Box = new_box;
+ m_Mask = new_mask;
+ return;
+ }
+ ASSERT(FALSE);
+}
+CFX_PathData::CFX_PathData()
+{
+ m_PointCount = m_AllocCount = 0;
+ m_pPoints = NULL;
+}
+CFX_PathData::~CFX_PathData()
+{
+ if (m_pPoints) {
+ FX_Free(m_pPoints);
+ }
+}
+FX_BOOL CFX_PathData::SetPointCount(int nPoints)
+{
+ m_PointCount = nPoints;
+ if (m_AllocCount < nPoints) {
+ if (m_pPoints) {
+ FX_Free(m_pPoints);
+ m_pPoints = NULL;
+ }
+ m_pPoints = FX_Alloc(FX_PATHPOINT, nPoints);
+ if (!m_pPoints) {
+ return FALSE;
+ }
+ m_AllocCount = nPoints;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_PathData::AllocPointCount(int nPoints)
+{
+ if (m_AllocCount < nPoints) {
+ FX_PATHPOINT* pNewBuf = FX_Alloc(FX_PATHPOINT, nPoints);
+ if (!pNewBuf) {
+ return FALSE;
+ }
+ if (m_PointCount) {
+ FXSYS_memcpy32(pNewBuf, m_pPoints, m_PointCount * sizeof(FX_PATHPOINT));
+ }
+ if (m_pPoints) {
+ FX_Free(m_pPoints);
+ }
+ m_pPoints = pNewBuf;
+ m_AllocCount = nPoints;
+ }
+ return TRUE;
+}
+CFX_PathData::CFX_PathData(const CFX_PathData& src)
+{
+ m_pPoints = NULL;
+ m_PointCount = m_AllocCount = src.m_PointCount;
+ m_pPoints = FX_Alloc(FX_PATHPOINT, src.m_PointCount);
+ if (!m_pPoints) {
+ return;
+ }
+ FXSYS_memcpy32(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
+}
+void CFX_PathData::TrimPoints(int nPoints)
+{
+ if (m_PointCount <= nPoints) {
+ return;
+ }
+ SetPointCount(nPoints);
+}
+FX_BOOL CFX_PathData::AddPointCount(int addPoints)
+{
+ int new_count = m_PointCount + addPoints;
+ if (!AllocPointCount(new_count)) {
+ return FALSE;
+ }
+ m_PointCount = new_count;
+ return TRUE;
+}
+FX_BOOL CFX_PathData::Append(const CFX_PathData* pSrc, const CFX_AffineMatrix* pMatrix)
+{
+ int old_count = m_PointCount;
+ if (!AddPointCount(pSrc->m_PointCount)) {
+ return FALSE;
+ }
+ FXSYS_memcpy32(m_pPoints + old_count, pSrc->m_pPoints, pSrc->m_PointCount * sizeof(FX_PATHPOINT));
+ if (pMatrix == NULL) {
+ return TRUE;
+ }
+ for (int i = 0; i < pSrc->m_PointCount; i ++) {
+ pMatrix->Transform(m_pPoints[old_count + i].m_PointX, m_pPoints[old_count + i].m_PointY);
+ }
+ return TRUE;
+}
+void CFX_PathData::SetPoint(int index, FX_FLOAT x, FX_FLOAT y, int flag)
+{
+ ASSERT(index < m_PointCount);
+ m_pPoints[index].m_PointX = x;
+ m_pPoints[index].m_PointY = y;
+ m_pPoints[index].m_Flag = flag;
+}
+FX_BOOL CFX_PathData::AppendRect(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top)
+{
+ int old_count = m_PointCount;
+ if (!AddPointCount(5)) {
+ return FALSE;
+ }
+ FX_PATHPOINT* pPoints = m_pPoints + old_count;
+ pPoints[0].m_PointX = pPoints[1].m_PointX = pPoints[4].m_PointX = left;
+ pPoints[2].m_PointX = pPoints[3].m_PointX = right;
+ pPoints[0].m_PointY = pPoints[3].m_PointY = pPoints[4].m_PointY = bottom;
+ pPoints[1].m_PointY = pPoints[2].m_PointY = top;
+ pPoints[0].m_Flag = FXPT_MOVETO;
+ pPoints[1].m_Flag = pPoints[2].m_Flag = pPoints[3].m_Flag = FXPT_LINETO;
+ pPoints[4].m_Flag = FXPT_LINETO | FXPT_CLOSEFIGURE;
+ return TRUE;
+}
+CFX_FloatRect CFX_PathData::GetBoundingBox() const
+{
+ CFX_FloatRect rect;
+ if (m_PointCount) {
+ rect.InitRect(m_pPoints[0].m_PointX, m_pPoints[0].m_PointY);
+ for (int i = 1; i < m_PointCount; i ++) {
+ rect.UpdateRect(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
+ }
+ }
+ return rect;
+}
+static void _UpdateLineEndPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y, FX_FLOAT end_x, FX_FLOAT end_y,
+ FX_FLOAT hw)
+{
+ if (start_x == end_x) {
+ if (start_y == end_y) {
+ rect.UpdateRect(end_x + hw, end_y + hw);
+ rect.UpdateRect(end_x - hw, end_y - hw);
+ return;
+ }
+ FX_FLOAT point_y;
+ if (end_y < start_y) {
+ point_y = end_y - hw;
+ } else {
+ point_y = end_y + hw;
+ }
+ rect.UpdateRect(end_x + hw, point_y);
+ rect.UpdateRect(end_x - hw, point_y);
+ return;
+ } else if (start_y == end_y) {
+ FX_FLOAT point_x;
+ if (end_x < start_x) {
+ point_x = end_x - hw;
+ } else {
+ point_x = end_x + hw;
+ }
+ rect.UpdateRect(point_x, end_y + hw);
+ rect.UpdateRect(point_x, end_y - hw);
+ return;
+ }
+ FX_FLOAT dx = end_x - start_x;
+ FX_FLOAT dy = end_y - start_y;
+ FX_FLOAT ll = FXSYS_sqrt2(dx, dy);
+ FX_FLOAT mx = end_x + hw * dx / ll;
+ FX_FLOAT my = end_y + hw * dy / ll;
+ FX_FLOAT dx1 = hw * dy / ll;
+ FX_FLOAT dy1 = hw * dx / ll;
+ rect.UpdateRect(mx - dx1, my + dy1);
+ rect.UpdateRect(mx + dx1, my - dy1);
+}
+static void _UpdateLineJoinPoints(CFX_FloatRect& rect, FX_FLOAT start_x, FX_FLOAT start_y,
+ FX_FLOAT middle_x, FX_FLOAT middle_y, FX_FLOAT end_x, FX_FLOAT end_y,
+ FX_FLOAT half_width, FX_FLOAT miter_limit)
+{
+ FX_FLOAT start_k = 0, start_c = 0, end_k = 0, end_c = 0, start_len = 0, start_dc = 0, end_len = 0, end_dc = 0;
+ FX_BOOL bStartVert = FXSYS_fabs(start_x - middle_x) < 1.0f / 20;
+ FX_BOOL bEndVert = FXSYS_fabs(middle_x - end_x) < 1.0f / 20;
+ if (bStartVert && bEndVert) {
+ int start_dir = middle_y > start_y ? 1 : -1;
+ FX_FLOAT point_y = middle_y + half_width * start_dir;
+ rect.UpdateRect(middle_x + half_width, point_y);
+ rect.UpdateRect(middle_x - half_width, point_y);
+ return;
+ }
+ if (!bStartVert) {
+ start_k = FXSYS_Div(middle_y - start_y, middle_x - start_x);
+ start_c = middle_y - FXSYS_Mul(start_k, middle_x);
+ start_len = FXSYS_sqrt2(start_x - middle_x, start_y - middle_y);
+ start_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, start_len, start_x - middle_x));
+ }
+ if (!bEndVert) {
+ end_k = FXSYS_Div(end_y - middle_y, end_x - middle_x);
+ end_c = middle_y - FXSYS_Mul(end_k, middle_x);
+ end_len = FXSYS_sqrt2(end_x - middle_x, end_y - middle_y);
+ end_dc = (FX_FLOAT)FXSYS_fabs(FXSYS_MulDiv(half_width, end_len, end_x - middle_x));
+ }
+ if (bStartVert) {
+ FX_FLOAT outside_x = start_x;
+ if (end_x < start_x) {
+ outside_x += half_width;
+ } else {
+ outside_x -= half_width;
+ }
+ FX_FLOAT outside_y;
+ if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
+ outside_y = FXSYS_Mul(end_k, outside_x) + end_c + end_dc;
+ } else {
+ outside_y = FXSYS_Mul(end_k, outside_x) + end_c - end_dc;
+ }
+ rect.UpdateRect(outside_x, outside_y);
+ return;
+ }
+ if (bEndVert) {
+ FX_FLOAT outside_x = end_x;
+ if (start_x < end_x) {
+ outside_x += half_width;
+ } else {
+ outside_x -= half_width;
+ }
+ FX_FLOAT outside_y;
+ if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
+ outside_y = FXSYS_Mul(start_k, outside_x) + start_c + start_dc;
+ } else {
+ outside_y = FXSYS_Mul(start_k, outside_x) + start_c - start_dc;
+ }
+ rect.UpdateRect(outside_x, outside_y);
+ return;
+ }
+ if (FXSYS_fabs(start_k - end_k) < 1.0f / 20) {
+ int start_dir = middle_x > start_x ? 1 : -1;
+ int end_dir = end_x > middle_x ? 1 : -1;
+ if (start_dir == end_dir) {
+ _UpdateLineEndPoints(rect, middle_x, middle_y, end_x, end_y, half_width);
+ } else {
+ _UpdateLineEndPoints(rect, start_x, start_y, middle_x, middle_y, half_width);
+ }
+ return;
+ }
+ FX_FLOAT start_outside_c = start_c;
+ if (end_y < FXSYS_Mul(start_k, end_x) + start_c) {
+ start_outside_c += start_dc;
+ } else {
+ start_outside_c -= start_dc;
+ }
+ FX_FLOAT end_outside_c = end_c;
+ if (start_y < FXSYS_Mul(end_k, start_x) + end_c) {
+ end_outside_c += end_dc;
+ } else {
+ end_outside_c -= end_dc;
+ }
+ FX_FLOAT join_x = FXSYS_Div(end_outside_c - start_outside_c, start_k - end_k);
+ FX_FLOAT join_y = FXSYS_Mul(start_k, join_x) + start_outside_c;
+ rect.UpdateRect(join_x, join_y);
+}
+CFX_FloatRect CFX_PathData::GetBoundingBox(FX_FLOAT line_width, FX_FLOAT miter_limit) const
+{
+ CFX_FloatRect rect(100000 * 1.0f, 100000 * 1.0f, -100000 * 1.0f, -100000 * 1.0f);
+ int iPoint = 0;
+ FX_FLOAT half_width = line_width;
+ int iStartPoint, iEndPoint, iMiddlePoint;
+ FX_BOOL bJoin;
+ while (iPoint < m_PointCount) {
+ if (m_pPoints[iPoint].m_Flag == FXPT_MOVETO) {
+ iStartPoint = iPoint + 1;
+ iEndPoint = iPoint;
+ bJoin = FALSE;
+ } else {
+ if (m_pPoints[iPoint].m_Flag == FXPT_BEZIERTO) {
+ rect.UpdateRect(m_pPoints[iPoint].m_PointX, m_pPoints[iPoint].m_PointY);
+ rect.UpdateRect(m_pPoints[iPoint + 1].m_PointX, m_pPoints[iPoint + 1].m_PointY);
+ iPoint += 2;
+ }
+ if (iPoint == m_PointCount - 1 || m_pPoints[iPoint + 1].m_Flag == FXPT_MOVETO) {
+ iStartPoint = iPoint - 1;
+ iEndPoint = iPoint;
+ bJoin = FALSE;
+ } else {
+ iStartPoint = iPoint - 1;
+ iMiddlePoint = iPoint;
+ iEndPoint = iPoint + 1;
+ bJoin = TRUE;
+ }
+ }
+ FX_FLOAT start_x = m_pPoints[iStartPoint].m_PointX;
+ FX_FLOAT start_y = m_pPoints[iStartPoint].m_PointY;
+ FX_FLOAT end_x = m_pPoints[iEndPoint].m_PointX;
+ FX_FLOAT end_y = m_pPoints[iEndPoint].m_PointY;
+ if (bJoin) {
+ FX_FLOAT middle_x = m_pPoints[iMiddlePoint].m_PointX;
+ FX_FLOAT middle_y = m_pPoints[iMiddlePoint].m_PointY;
+ _UpdateLineJoinPoints(rect, start_x, start_y, middle_x, middle_y, end_x, end_y, half_width, miter_limit);
+ } else {
+ _UpdateLineEndPoints(rect, start_x, start_y, end_x, end_y, half_width);
+ }
+ iPoint ++;
+ }
+ return rect;
+}
+void CFX_PathData::Transform(const CFX_AffineMatrix* pMatrix)
+{
+ if (pMatrix == NULL) {
+ return;
+ }
+ for (int i = 0; i < m_PointCount; i ++) {
+ pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY);
+ }
+}
+const int g_Distant[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+FX_BOOL CFX_PathData::GetZeroAreaPath(CFX_PathData& NewPath, CFX_AffineMatrix* pMatrix, FX_BOOL&bThin, FX_BOOL bAdjust) const
+{
+ if (m_PointCount < 3) {
+ return FALSE;
+ }
+ if (m_PointCount == 3 && (m_pPoints[0].m_Flag & FXPT_TYPE) == FXPT_MOVETO &&
+ (m_pPoints[1].m_Flag & FXPT_TYPE) == FXPT_LINETO && (m_pPoints[2].m_Flag & FXPT_TYPE) == FXPT_LINETO
+ && m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) {
+ NewPath.AddPointCount(2);
+ if (bAdjust) {
+ if (pMatrix) {
+ FX_FLOAT x = m_pPoints[0].m_PointX, y = m_pPoints[0].m_PointY;
+ pMatrix->TransformPoint(x, y);
+ x = (int)x + 0.5f;
+ y = (int)y + 0.5f;
+ NewPath.SetPoint(0, x, y, FXPT_MOVETO);
+ x = m_pPoints[1].m_PointX, y = m_pPoints[1].m_PointY;
+ pMatrix->TransformPoint(x, y);
+ x = (int)x + 0.5f;
+ y = (int)y + 0.5f;
+ NewPath.SetPoint(1, x, y, FXPT_LINETO);
+ pMatrix->SetIdentity();
+ } else {
+ FX_FLOAT x = (int)m_pPoints[0].m_PointX + 0.5f, y = (int)m_pPoints[0].m_PointY + 0.5f;
+ NewPath.SetPoint(0, x, y, FXPT_MOVETO);
+ x = (int)m_pPoints[1].m_PointX + 0.5f, y = (int)m_pPoints[1].m_PointY + 0.5f;
+ NewPath.SetPoint(1, x, y, FXPT_LINETO);
+ }
+ } else {
+ NewPath.SetPoint(0, m_pPoints[0].m_PointX, m_pPoints[0].m_PointY, FXPT_MOVETO);
+ NewPath.SetPoint(1, m_pPoints[1].m_PointX, m_pPoints[1].m_PointY, FXPT_LINETO);
+ }
+ if (m_pPoints[0].m_PointX != m_pPoints[1].m_PointX && m_pPoints[0].m_PointY != m_pPoints[1].m_PointY) {
+ bThin = TRUE;
+ }
+ return TRUE;
+ }
+ if (((m_PointCount > 3) && (m_PointCount % 2))) {
+ int mid = m_PointCount / 2;
+ FX_BOOL bZeroArea = FALSE;
+ CFX_PathData t_path;
+ for (int i = 0; i < mid; i++) {
+ if (!(m_pPoints[mid - i - 1].m_PointX == m_pPoints[mid + i + 1].m_PointX
+ && m_pPoints[mid - i - 1].m_PointY == m_pPoints[mid + i + 1].m_PointY &&
+ ((m_pPoints[mid - i - 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && (m_pPoints[mid + i + 1].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO))) {
+ bZeroArea = TRUE;
+ break;
+ }
+ int new_count = t_path.GetPointCount();
+ t_path.AddPointCount(2);
+ t_path.SetPoint(new_count, m_pPoints[mid - i].m_PointX, m_pPoints[mid - i].m_PointY, FXPT_MOVETO);
+ t_path.SetPoint(new_count + 1, m_pPoints[mid - i - 1].m_PointX, m_pPoints[mid - i - 1].m_PointY, FXPT_LINETO);
+ }
+ if (!bZeroArea) {
+ NewPath.Append(&t_path, NULL);
+ bThin = TRUE;
+ return TRUE;
+ }
+ }
+ int stratPoint = 0;
+ int next = 0, i;
+ for (i = 0; i < m_PointCount; i++) {
+ int point_type = m_pPoints[i].m_Flag & FXPT_TYPE;
+ if (point_type == FXPT_MOVETO) {
+ stratPoint = i;
+ } else if (point_type == FXPT_LINETO) {
+ next = (i + 1 - stratPoint) % (m_PointCount - stratPoint) + stratPoint;
+ if ((m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_BEZIERTO && (m_pPoints[next].m_Flag & FXPT_TYPE) != FXPT_MOVETO) {
+ if((m_pPoints[i - 1].m_PointX == m_pPoints[i].m_PointX && m_pPoints[i].m_PointX == m_pPoints[next].m_PointX)
+ && ((m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY) * (m_pPoints[i].m_PointY - m_pPoints[next].m_PointY) > 0)) {
+ int pre = i;
+ if (FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[i - 1].m_PointY)
+ < FXSYS_fabs(m_pPoints[i].m_PointY - m_pPoints[next].m_PointY)) {
+ pre --;
+ next--;
+ }
+ int new_count = NewPath.GetPointCount();
+ NewPath.AddPointCount(2);
+ NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoints[pre].m_PointY, FXPT_MOVETO);
+ NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_pPoints[next].m_PointY, FXPT_LINETO);
+ } else if((m_pPoints[i - 1].m_PointY == m_pPoints[i].m_PointY && m_pPoints[i].m_PointY == m_pPoints[next].m_PointY)
+ && ((m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX) * (m_pPoints[i].m_PointX - m_pPoints[next].m_PointX) > 0)) {
+ int pre = i;
+ if (FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[i - 1].m_PointX)
+ < FXSYS_fabs(m_pPoints[i].m_PointX - m_pPoints[next].m_PointX)) {
+ pre --;
+ next--;
+ }
+ int new_count = NewPath.GetPointCount();
+ NewPath.AddPointCount(2);
+ NewPath.SetPoint(new_count, m_pPoints[pre].m_PointX, m_pPoints[pre].m_PointY, FXPT_MOVETO);
+ NewPath.SetPoint(new_count + 1, m_pPoints[next].m_PointX, m_pPoints[next].m_PointY, FXPT_LINETO);
+ } else if ((m_pPoints[i - 1].m_Flag & FXPT_TYPE) == FXPT_MOVETO && (m_pPoints[next].m_Flag & FXPT_TYPE) == FXPT_LINETO &&
+ m_pPoints[i - 1].m_PointX == m_pPoints[next].m_PointX && m_pPoints[i - 1].m_PointY == m_pPoints[next].m_PointY
+ && m_pPoints[next].m_Flag & FXPT_CLOSEFIGURE) {
+ int new_count = NewPath.GetPointCount();
+ NewPath.AddPointCount(2);
+ NewPath.SetPoint(new_count, m_pPoints[i - 1].m_PointX, m_pPoints[i - 1].m_PointY, FXPT_MOVETO);
+ NewPath.SetPoint(new_count + 1, m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, FXPT_LINETO);
+ bThin = TRUE;
+ }
+ }
+ } else if (point_type == FXPT_BEZIERTO) {
+ i += 2;
+ continue;
+ }
+ }
+ if (m_PointCount > 3 && NewPath.GetPointCount()) {
+ bThin = TRUE;
+ }
+ if (NewPath.GetPointCount() == 0) {
+ return FALSE;
+ }
+ return TRUE;
+}
+FX_BOOL CFX_PathData::IsRect() const
+{
+ if (m_PointCount != 5 && m_PointCount != 4) {
+ return FALSE;
+ }
+ if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX ||
+ m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
+ (m_pPoints[0].m_PointX == m_pPoints[2].m_PointX && m_pPoints[0].m_PointY == m_pPoints[2].m_PointY) ||
+ (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
+ return FALSE;
+ }
+ if (m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
+ return FALSE;
+ }
+ for (int i = 1; i < 4; i ++) {
+ if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) {
+ return FALSE;
+ }
+ if (m_pPoints[i].m_PointX != m_pPoints[i - 1].m_PointX && m_pPoints[i].m_PointY != m_pPoints[i - 1].m_PointY) {
+ return FALSE;
+ }
+ }
+ return m_PointCount == 5 || (m_pPoints[3].m_Flag & FXPT_CLOSEFIGURE);
+}
+FX_BOOL CFX_PathData::IsRect(const CFX_AffineMatrix* pMatrix, CFX_FloatRect* pRect) const
+{
+ if (pMatrix == NULL) {
+ if (!IsRect()) {
+ return FALSE;
+ }
+ if (pRect) {
+ pRect->left = m_pPoints[0].m_PointX;
+ pRect->right = m_pPoints[2].m_PointX;
+ pRect->bottom = m_pPoints[0].m_PointY;
+ pRect->top = m_pPoints[2].m_PointY;
+ pRect->Normalize();
+ }
+ return TRUE;
+ }
+ if (m_PointCount != 5 && m_PointCount != 4) {
+ return FALSE;
+ }
+ if ((m_PointCount == 5 && (m_pPoints[0].m_PointX != m_pPoints[4].m_PointX || m_pPoints[0].m_PointY != m_pPoints[4].m_PointY)) ||
+ (m_pPoints[1].m_PointX == m_pPoints[3].m_PointX && m_pPoints[1].m_PointY == m_pPoints[3].m_PointY)) {
+ return FALSE;
+ }
+ if (m_PointCount == 4 && m_pPoints[0].m_PointX != m_pPoints[3].m_PointX && m_pPoints[0].m_PointY != m_pPoints[3].m_PointY) {
+ return FALSE;
+ }
+ FX_FLOAT x[5], y[5];
+ for (int i = 0; i < m_PointCount; i ++) {
+ pMatrix->Transform(m_pPoints[i].m_PointX, m_pPoints[i].m_PointY, x[i], y[i]);
+ if (i) {
+ if ((m_pPoints[i].m_Flag & FXPT_TYPE) != FXPT_LINETO) {
+ return FALSE;
+ }
+ if (x[i] != x[i - 1] && y[i] != y[i - 1]) {
+ return FALSE;
+ }
+ }
+ }
+ if (pRect) {
+ pRect->left = x[0];
+ pRect->right = x[2];
+ pRect->bottom = y[0];
+ pRect->top = y[2];
+ pRect->Normalize();
+ }
+ return TRUE;
+}
+FX_BOOL CFX_PathData::Copy(const CFX_PathData &src)
+{
+ if (!SetPointCount(src.m_PointCount)) {
+ return FALSE;
+ }
+ FXSYS_memcpy32(m_pPoints, src.m_pPoints, sizeof(FX_PATHPOINT) * m_PointCount);
+ return TRUE;
+}
+CFX_GraphStateData::CFX_GraphStateData()
+{
+ m_LineCap = LineCapButt;
+ m_DashCount = 0;
+ m_DashArray = NULL;
+ m_DashPhase = 0;
+ m_LineJoin = LineJoinMiter;
+ m_MiterLimit = 10 * 1.0f;
+ m_LineWidth = 1.0f;
+}
+CFX_GraphStateData::CFX_GraphStateData(const CFX_GraphStateData& src)
+{
+ m_DashArray = NULL;
+ Copy(src);
+}
+void CFX_GraphStateData::Copy(const CFX_GraphStateData& src)
+{
+ m_LineCap = src.m_LineCap;
+ m_DashCount = src.m_DashCount;
+ if (m_DashArray) {
+ FX_Free(m_DashArray);
+ }
+ m_DashArray = NULL;
+ m_DashPhase = src.m_DashPhase;
+ m_LineJoin = src.m_LineJoin;
+ m_MiterLimit = src.m_MiterLimit;
+ m_LineWidth = src.m_LineWidth;
+ if (m_DashCount) {
+ m_DashArray = FX_Alloc(FX_FLOAT, m_DashCount);
+ if (!m_DashArray) {
+ return;
+ }
+ FXSYS_memcpy32(m_DashArray, src.m_DashArray, m_DashCount * sizeof(FX_FLOAT));
+ }
+}
+CFX_GraphStateData::~CFX_GraphStateData()
+{
+ if (m_DashArray) {
+ FX_Free(m_DashArray);
+ }
+}
+void CFX_GraphStateData::SetDashCount(int count)
+{
+ if (m_DashArray) {
+ FX_Free(m_DashArray);
+ }
+ m_DashArray = NULL;
+ m_DashCount = count;
+ if (count == 0) {
+ return;
+ }
+ m_DashArray = FX_Alloc(FX_FLOAT, count);
+}
diff --git a/core/src/fxge/ge/fx_ge_ps.cpp b/core/src/fxge/ge/fx_ge_ps.cpp
index a39ab2dee0..d664b706b0 100644
--- a/core/src/fxge/ge/fx_ge_ps.cpp
+++ b/core/src/fxge/ge/fx_ge_ps.cpp
@@ -1,657 +1,657 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#include "../../../include/fxcodec/fx_codec.h"
-#include "text_int.h"
-struct PSGlyph {
- CFX_Font* m_pFont;
- FX_DWORD m_GlyphIndex;
- FX_BOOL m_bGlyphAdjust;
- FX_FLOAT m_AdjustMatrix[4];
-};
-class CPSFont : public CFX_Object
-{
-public:
- PSGlyph m_Glyphs[256];
- int m_nGlyphs;
-};
-CFX_PSRenderer::CFX_PSRenderer()
-{
- m_pOutput = NULL;
- m_bColorSet = m_bGraphStateSet = FALSE;
- m_bInited = FALSE;
-}
-CFX_PSRenderer::~CFX_PSRenderer()
-{
- for (int i = 0; i < (int)m_PSFontList.GetSize(); i ++) {
- CPSFont* pFont = m_PSFontList[i];
- delete pFont;
- }
-}
-#define OUTPUT_PS(str) m_pOutput->OutputPS(str, sizeof str-1)
-void CFX_PSRenderer::Init(IFX_PSOutput* pOutput, int pslevel, int width, int height, FX_BOOL bCmykOutput)
-{
- m_PSLevel = pslevel;
- m_pOutput = pOutput;
- m_ClipBox.left = m_ClipBox.top = 0;
- m_ClipBox.right = width;
- m_ClipBox.bottom = height;
- m_bCmykOutput = bCmykOutput;
-}
-FX_BOOL CFX_PSRenderer::StartRendering()
-{
- if (m_bInited) {
- return TRUE;
- }
- static const char init_str[] = "\nsave\n/im/initmatrix load def\n"
- "/n/newpath load def/m/moveto load def/l/lineto load def/c/curveto load def/h/closepath load def\n"
- "/f/fill load def/F/eofill load def/s/stroke load def/W/clip load def/W*/eoclip load def\n"
- "/rg/setrgbcolor load def/k/setcmykcolor load def\n"
- "/J/setlinecap load def/j/setlinejoin load def/w/setlinewidth load def/M/setmiterlimit load def/d/setdash load def\n"
- "/q/gsave load def/Q/grestore load def/iM/imagemask load def\n"
- "/Tj/show load def/Ff/findfont load def/Fs/scalefont load def/Sf/setfont load def\n"
- "/cm/concat load def/Cm/currentmatrix load def/mx/matrix load def/sm/setmatrix load def\n"
- ;
- OUTPUT_PS(init_str);
- m_bInited = TRUE;
- return TRUE;
-}
-void CFX_PSRenderer::EndRendering()
-{
- if (m_bInited) {
- OUTPUT_PS("\nrestore\n");
- }
- m_bInited = FALSE;
-}
-void CFX_PSRenderer::SaveState()
-{
- StartRendering();
- OUTPUT_PS("q\n");
- m_ClipBoxStack.Add(m_ClipBox);
-}
-void CFX_PSRenderer::RestoreState(FX_BOOL bKeepSaved)
-{
- StartRendering();
- if (bKeepSaved) {
- OUTPUT_PS("Q\nq\n");
- } else {
- OUTPUT_PS("Q\n");
- }
- m_bColorSet = m_bGraphStateSet = FALSE;
- m_ClipBox = m_ClipBoxStack.GetAt(m_ClipBoxStack.GetSize() - 1);
- if (!bKeepSaved) {
- m_ClipBoxStack.RemoveAt(m_ClipBoxStack.GetSize() - 1);
- }
-}
-void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device)
-{
- int nPoints = pPathData->GetPointCount();
- CFX_ByteTextBuf buf;
- buf.EstimateSize(nPoints * 10);
- for (int i = 0; i < nPoints; i ++) {
- FX_BYTE flag = pPathData->GetFlag(i);
- FX_FLOAT x = pPathData->GetPointX(i);
- FX_FLOAT y = pPathData->GetPointY(i);
- if (pObject2Device) {
- pObject2Device->Transform(x, y);
- }
- buf << x << FX_BSTRC(" ") << y;
- switch (flag & FXPT_TYPE) {
- case FXPT_MOVETO:
- buf << FX_BSTRC(" m ");
- break;
- case FXPT_LINETO:
- if (flag & FXPT_CLOSEFIGURE) {
- buf << FX_BSTRC(" l h ");
- } else {
- buf << FX_BSTRC(" l ");
- }
- break;
- case FXPT_BEZIERTO: {
- FX_FLOAT x1 = pPathData->GetPointX(i + 1);
- FX_FLOAT x2 = pPathData->GetPointX(i + 2);
- FX_FLOAT y1 = pPathData->GetPointY(i + 1);
- FX_FLOAT y2 = pPathData->GetPointY(i + 2);
- if (pObject2Device) {
- pObject2Device->Transform(x1, y1);
- pObject2Device->Transform(x2, y2);
- }
- buf << FX_BSTRC(" ") << x1 << FX_BSTRC(" ") << y1 << FX_BSTRC(" ") << x2 << FX_BSTRC(" ") << y2;
- if (flag & FXPT_CLOSEFIGURE) {
- buf << FX_BSTRC(" c h\n");
- } else {
- buf << FX_BSTRC(" c\n");
- }
- i += 2;
- break;
- }
- }
- }
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
-}
-void CFX_PSRenderer::SetClip_PathFill(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- int fill_mode
- )
-{
- StartRendering();
- OutputPath(pPathData, pObject2Device);
- CFX_FloatRect rect = pPathData->GetBoundingBox();
- if (pObject2Device) {
- rect.Transform(pObject2Device);
- }
- m_ClipBox.Intersect(rect.GetOutterRect());
- if ((fill_mode & 3) == FXFILL_WINDING) {
- OUTPUT_PS("W n\n");
- } else {
- OUTPUT_PS("W* n\n");
- }
-}
-void CFX_PSRenderer::SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState
- )
-{
- StartRendering();
- SetGraphState(pGraphState);
- if (pObject2Device) {
- CFX_ByteTextBuf buf;
- buf << FX_BSTRC("mx Cm [") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ") <<
- pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d << FX_BSTRC(" ") << pObject2Device->e <<
- FX_BSTRC(" ") << pObject2Device->f << FX_BSTRC("]cm ");
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
- }
- OutputPath(pPathData, NULL);
- CFX_FloatRect rect = pPathData->GetBoundingBox(pGraphState->m_LineWidth, pGraphState->m_MiterLimit);
- rect.Transform(pObject2Device);
- m_ClipBox.Intersect(rect.GetOutterRect());
- if (pObject2Device) {
- OUTPUT_PS("strokepath W n sm\n");
- } else {
- OUTPUT_PS("strokepath W n\n");
- }
-}
-FX_BOOL CFX_PSRenderer::DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color,
- FX_DWORD stroke_color,
- int fill_mode,
- int alpha_flag,
- void* pIccTransform
- )
-{
- StartRendering();
- int fill_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(fill_color);
- int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_STROKE(alpha_flag) : FXARGB_A(stroke_color);
- if (fill_alpha && fill_alpha < 255) {
- return FALSE;
- }
- if (stroke_alpha && stroke_alpha < 255) {
- return FALSE;
- }
- if (fill_alpha == 0 && stroke_alpha == 0) {
- return FALSE;
- }
- if (stroke_alpha) {
- SetGraphState(pGraphState);
- if (pObject2Device) {
- CFX_ByteTextBuf buf;
- buf << FX_BSTRC("mx Cm [") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ") <<
- pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d << FX_BSTRC(" ") << pObject2Device->e <<
- FX_BSTRC(" ") << pObject2Device->f << FX_BSTRC("]cm ");
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
- }
- }
- OutputPath(pPathData, stroke_alpha ? NULL : pObject2Device);
- if (fill_mode && fill_alpha) {
- SetColor(fill_color, alpha_flag, pIccTransform);
- if ((fill_mode & 3) == FXFILL_WINDING) {
- if (stroke_alpha) {
- OUTPUT_PS("q f Q ");
- } else {
- OUTPUT_PS("f");
- }
- } else if ((fill_mode & 3) == FXFILL_ALTERNATE) {
- if (stroke_alpha) {
- OUTPUT_PS("q F Q ");
- } else {
- OUTPUT_PS("F");
- }
- }
- }
- if (stroke_alpha) {
- SetColor(stroke_color, alpha_flag, pIccTransform);
- if (pObject2Device) {
- OUTPUT_PS("s sm");
- } else {
- OUTPUT_PS("s");
- }
- }
- OUTPUT_PS("\n");
- return TRUE;
-}
-void CFX_PSRenderer::SetGraphState(const CFX_GraphStateData* pGraphState)
-{
- CFX_ByteTextBuf buf;
- if (!m_bGraphStateSet || m_CurGraphState.m_LineCap != pGraphState->m_LineCap) {
- buf << pGraphState->m_LineCap << FX_BSTRC(" J\n");
- }
- if (!m_bGraphStateSet || m_CurGraphState.m_DashCount != pGraphState->m_DashCount ||
- FXSYS_memcmp32(m_CurGraphState.m_DashArray, pGraphState->m_DashArray, sizeof(FX_FLOAT)*m_CurGraphState.m_DashCount)) {
- buf << FX_BSTRC("[");
- for (int i = 0; i < pGraphState->m_DashCount; i ++) {
- buf << pGraphState->m_DashArray[i] << FX_BSTRC(" ");
- }
- buf << FX_BSTRC("]") << pGraphState->m_DashPhase << FX_BSTRC(" d\n");
- }
- if (!m_bGraphStateSet || m_CurGraphState.m_LineJoin != pGraphState->m_LineJoin) {
- buf << pGraphState->m_LineJoin << FX_BSTRC(" j\n");
- }
- if (!m_bGraphStateSet || m_CurGraphState.m_LineWidth != pGraphState->m_LineWidth) {
- buf << pGraphState->m_LineWidth << FX_BSTRC(" w\n");
- }
- if (!m_bGraphStateSet || m_CurGraphState.m_MiterLimit != pGraphState->m_MiterLimit) {
- buf << pGraphState->m_MiterLimit << FX_BSTRC(" M\n");
- }
- m_CurGraphState.Copy(*pGraphState);
- m_bGraphStateSet = TRUE;
- if (buf.GetSize()) {
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
- }
-}
-static void FaxCompressData(FX_LPBYTE src_buf, int width, int height, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
-{
- CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
- if (width * height > 128 && pEncoders && pEncoders->GetFaxModule()->Encode(src_buf, width, height, (width + 7) / 8, dest_buf, dest_size)) {
- FX_Free(src_buf);
- } else {
- dest_buf = src_buf;
- dest_size = (width + 7) / 8 * height;
- }
-}
-static void PSCompressData(int PSLevel, FX_LPBYTE src_buf, FX_DWORD src_size,
- FX_LPBYTE& output_buf, FX_DWORD& output_size, FX_LPCSTR& filter)
-{
- output_buf = src_buf;
- output_size = src_size;
- filter = "";
- if (src_size < 1024) {
- return;
- }
- CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
- FX_LPBYTE dest_buf = NULL;
- FX_DWORD dest_size = src_size;
- if (PSLevel >= 3) {
- if (pEncoders && pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, dest_size)) {
- filter = "/FlateDecode filter ";
- }
- } else {
- if (pEncoders && pEncoders->GetBasicModule()->RunLengthEncode(src_buf, src_size, dest_buf, dest_size)) {
- filter = "/RunLengthDecode filter ";
- }
- }
- if (dest_size < src_size) {
- output_buf = dest_buf;
- output_size = dest_size;
- } else {
- filter = NULL;
- if (dest_buf) {
- FX_Free(dest_buf);
- }
- }
-}
-FX_BOOL CFX_PSRenderer::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int left, int top,
- int alpha_flag, void* pIccTransform)
-{
- StartRendering();
- CFX_AffineMatrix matrix((FX_FLOAT)(pSource->GetWidth()), 0.0f, 0.0f, -(FX_FLOAT)(pSource->GetHeight()),
- (FX_FLOAT)(left), (FX_FLOAT)(top + pSource->GetHeight()));
- return DrawDIBits(pSource, color, &matrix, 0, alpha_flag, pIccTransform);
-}
-FX_BOOL CFX_PSRenderer::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD flags,
- int alpha_flag, void* pIccTransform)
-{
- StartRendering();
- CFX_AffineMatrix matrix((FX_FLOAT)(dest_width), 0.0f, 0.0f, (FX_FLOAT)(-dest_height),
- (FX_FLOAT)(dest_left), (FX_FLOAT)(dest_top + dest_height));
- return DrawDIBits(pSource, color, &matrix, flags, alpha_flag, pIccTransform);
-}
-FX_BOOL CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD flags,
- int alpha_flag, void* pIccTransform)
-{
- StartRendering();
- if ((pMatrix->a == 0 && pMatrix->b == 0) || (pMatrix->c == 0 && pMatrix->d == 0)) {
- return TRUE;
- }
- if (pSource->HasAlpha()) {
- return FALSE;
- }
- int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(color) : FXARGB_A(color);
- if (pSource->IsAlphaMask() && (alpha < 255 || pSource->GetBPP() != 1)) {
- return FALSE;
- }
- OUTPUT_PS("q\n");
- CFX_ByteTextBuf buf;
- buf << FX_BSTRC("[") << pMatrix->a << FX_BSTRC(" ") << pMatrix->b << FX_BSTRC(" ") <<
- pMatrix->c << FX_BSTRC(" ") << pMatrix->d << FX_BSTRC(" ") << pMatrix->e <<
- FX_BSTRC(" ") << pMatrix->f << FX_BSTRC("]cm ");
- int width = pSource->GetWidth();
- int height = pSource->GetHeight();
- buf << width << FX_BSTRC(" ") << height;
- if (pSource->GetBPP() == 1 && pSource->GetPalette() == NULL) {
- int pitch = (width + 7) / 8;
- FX_DWORD src_size = height * pitch;
- FX_LPBYTE src_buf = FX_Alloc(FX_BYTE, src_size);
- if (!src_buf) {
- return FALSE;
- }
- for (int row = 0; row < height; row ++) {
- FX_LPCBYTE src_scan = pSource->GetScanline(row);
- FXSYS_memcpy32(src_buf + row * pitch, src_scan, pitch);
- }
- FX_LPBYTE output_buf;
- FX_DWORD output_size;
- FaxCompressData(src_buf, width, height, output_buf, output_size);
- if (pSource->IsAlphaMask()) {
- SetColor(color, alpha_flag, pIccTransform);
- m_bColorSet = FALSE;
- buf << FX_BSTRC(" true[");
- } else {
- buf << FX_BSTRC(" 1[");
- }
- buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height <<
- FX_BSTRC("]currentfile/ASCII85Decode filter ");
- if (output_buf != src_buf)
- buf << FX_BSTRC("<</K -1/EndOfBlock false/Columns ") << width << FX_BSTRC("/Rows ") << height <<
- FX_BSTRC(">>/CCITTFaxDecode filter ");
- if (pSource->IsAlphaMask()) {
- buf << FX_BSTRC("iM\n");
- } else {
- buf << FX_BSTRC("false 1 colorimage\n");
- }
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
- WritePSBinary(output_buf, output_size);
- FX_Free(output_buf);
- } else {
- CFX_DIBSource* pConverted = (CFX_DIBSource*)pSource;
- if (pIccTransform) {
- FXDIB_Format format = m_bCmykOutput ? FXDIB_Cmyk : FXDIB_Rgb;
- pConverted = pSource->CloneConvert(format, NULL, pIccTransform);
- } else {
- switch (pSource->GetFormat()) {
- case FXDIB_1bppRgb:
- case FXDIB_Rgb32:
- pConverted = pSource->CloneConvert(FXDIB_Rgb);
- break;
- case FXDIB_8bppRgb:
- if (pSource->GetPalette() != NULL) {
- pConverted = pSource->CloneConvert(FXDIB_Rgb);
- }
- break;
- case FXDIB_1bppCmyk:
- pConverted = pSource->CloneConvert(FXDIB_Cmyk);
- break;
- case FXDIB_8bppCmyk:
- if (pSource->GetPalette() != NULL) {
- pConverted = pSource->CloneConvert(FXDIB_Cmyk);
- }
- break;
- default:
- break;
- }
- }
- if (pConverted == NULL) {
- OUTPUT_PS("\nQ\n");
- return FALSE;
- }
- int Bpp = pConverted->GetBPP() / 8;
- FX_LPBYTE output_buf = NULL;
- FX_STRSIZE output_size = 0;
- FX_LPCSTR filter = NULL;
- if (flags & FXRENDER_IMAGE_LOSSY) {
- CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
- if (pEncoders && pEncoders->GetJpegModule()->Encode(pConverted, output_buf, output_size)) {
- filter = "/DCTDecode filter ";
- }
- }
- if (filter == NULL) {
- int src_pitch = width * Bpp;
- output_size = height * src_pitch;
- output_buf = FX_Alloc(FX_BYTE, output_size);
- if (!output_buf) {
- if (pConverted != pSource) {
- delete pConverted;
- pConverted = NULL;
- }
- return FALSE;
- }
- for (int row = 0; row < height; row ++) {
- FX_LPCBYTE src_scan = pConverted->GetScanline(row);
- FX_LPBYTE dest_scan = output_buf + row * src_pitch;
- if (Bpp == 3) {
- for (int col = 0; col < width; col ++) {
- *dest_scan++ = src_scan[2];
- *dest_scan++ = src_scan[1];
- *dest_scan++ = *src_scan;
- src_scan += 3;
- }
- } else {
- FXSYS_memcpy32(dest_scan, src_scan, src_pitch);
- }
- }
- FX_LPBYTE compressed_buf;
- FX_DWORD compressed_size;
- PSCompressData(m_PSLevel, output_buf, output_size, compressed_buf, compressed_size, filter);
- if (output_buf != compressed_buf) {
- FX_Free(output_buf);
- }
- output_buf = compressed_buf;
- output_size = compressed_size;
- }
- if (pConverted != pSource) {
- delete pConverted;
- pConverted = NULL;
- }
- buf << FX_BSTRC(" 8[");
- buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height << FX_BSTRC("]");
- buf << FX_BSTRC("currentfile/ASCII85Decode filter ");
- if (filter) {
- buf << filter;
- }
- buf << FX_BSTRC("false ") << Bpp;
- buf << FX_BSTRC(" colorimage\n");
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
- WritePSBinary(output_buf, output_size);
- FX_Free(output_buf);
- }
- OUTPUT_PS("\nQ\n");
- return TRUE;
-}
-void CFX_PSRenderer::SetColor(FX_DWORD color, int alpha_flag, void* pIccTransform)
-{
- if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
- pIccTransform = NULL;
- }
- FX_BOOL bCMYK = FALSE;
- if (pIccTransform) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
- FX_LPBYTE pColor = (FX_LPBYTE)&color;
- pIccModule->TranslateScanline(pIccTransform, pColor, pColor, 1);
- color = m_bCmykOutput ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
- bCMYK = m_bCmykOutput;
- } else {
- bCMYK = FXGETFLAG_COLORTYPE(alpha_flag);
- }
- if (bCMYK != m_bCmykOutput || !m_bColorSet || m_LastColor != color) {
- CFX_ByteTextBuf buf;
- if (bCMYK) {
- buf << FXSYS_GetCValue(color) / 255.0 << FX_BSTRC(" ") << FXSYS_GetMValue(color) / 255.0 << FX_BSTRC(" ")
- << FXSYS_GetYValue(color) / 255.0 << FX_BSTRC(" ") << FXSYS_GetKValue(color) / 255.0 << FX_BSTRC(" k\n");
- } else {
- buf << FXARGB_R(color) / 255.0 << FX_BSTRC(" ") << FXARGB_G(color) / 255.0 << FX_BSTRC(" ")
- << FXARGB_B(color) / 255.0 << FX_BSTRC(" rg\n");
- }
- if (bCMYK == m_bCmykOutput) {
- m_bColorSet = TRUE;
- m_LastColor = color;
- }
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
- }
-}
-void CFX_PSRenderer::FindPSFontGlyph(CFX_FaceCache* pFaceCache, CFX_Font* pFont, const FXTEXT_CHARPOS& charpos,
- int& ps_fontnum, int &ps_glyphindex)
-{
- for (int i = 0; i < (int)m_PSFontList.GetSize(); i ++) {
- CPSFont* pPSFont = m_PSFontList[i];
- for (int j = 0; j < pPSFont->m_nGlyphs; j ++)
- if (pPSFont->m_Glyphs[j].m_pFont == pFont && pPSFont->m_Glyphs[j].m_GlyphIndex == charpos.m_GlyphIndex) {
- if ((!pPSFont->m_Glyphs[j].m_bGlyphAdjust && !charpos.m_bGlyphAdjust) ||
- (pPSFont->m_Glyphs[j].m_bGlyphAdjust && charpos.m_bGlyphAdjust &&
- (FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[0] - charpos.m_AdjustMatrix[0]) < 0.01 &&
- FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[1] - charpos.m_AdjustMatrix[1]) < 0.01 &&
- FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[2] - charpos.m_AdjustMatrix[2]) < 0.01 &&
- FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[3] - charpos.m_AdjustMatrix[3]) < 0.01))) {
- ps_fontnum = i;
- ps_glyphindex = j;
- return;
- }
- }
- }
- if (m_PSFontList.GetSize() == 0 || m_PSFontList[m_PSFontList.GetSize() - 1]->m_nGlyphs == 256) {
- CPSFont* pPSFont = FX_NEW CPSFont;
- if (!pPSFont) {
- return;
- }
- pPSFont->m_nGlyphs = 0;
- m_PSFontList.Add(pPSFont);
- CFX_ByteTextBuf buf;
- buf << FX_BSTRC("8 dict begin/FontType 3 def/FontMatrix[1 0 0 1 0 0]def\n"
- "/FontBBox[0 0 0 0]def/Encoding 256 array def 0 1 255{Encoding exch/.notdef put}for\n"
- "/CharProcs 1 dict def CharProcs begin/.notdef {} def end\n"
- "/BuildGlyph{1 0 -10 -10 10 10 setcachedevice exch/CharProcs get exch 2 copy known not{pop/.notdef}if get exec}bind def\n"
- "/BuildChar{1 index/Encoding get exch get 1 index/BuildGlyph get exec}bind def\n"
- "currentdict end\n");
- buf << FX_BSTRC("/X") << m_PSFontList.GetSize() - 1 << FX_BSTRC(" exch definefont pop\n");
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
- buf.Clear();
- }
- ps_fontnum = m_PSFontList.GetSize() - 1;
- CPSFont* pPSFont = m_PSFontList[ps_fontnum];
- ps_glyphindex = pPSFont->m_nGlyphs;
- pPSFont->m_Glyphs[ps_glyphindex].m_GlyphIndex = charpos.m_GlyphIndex;
- pPSFont->m_Glyphs[ps_glyphindex].m_pFont = pFont;
- pPSFont->m_Glyphs[ps_glyphindex].m_bGlyphAdjust = charpos.m_bGlyphAdjust;
- if (charpos.m_bGlyphAdjust) {
- pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[0] = charpos.m_AdjustMatrix[0];
- pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[1] = charpos.m_AdjustMatrix[1];
- pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[2] = charpos.m_AdjustMatrix[2];
- pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[3] = charpos.m_AdjustMatrix[3];
- }
- pPSFont->m_nGlyphs ++;
- CFX_AffineMatrix matrix;
- if (charpos.m_bGlyphAdjust)
- matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1],
- charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0);
- matrix.Concat(1.0f, 0, 0, 1.0f, 0, 0);
- const CFX_PathData* pPathData = pFaceCache->LoadGlyphPath(pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth);
- if (pPathData == NULL) {
- return;
- }
- CFX_PathData TransformedPath(*pPathData);
- if (charpos.m_bGlyphAdjust) {
- TransformedPath.Transform(&matrix);
- }
- CFX_ByteTextBuf buf;
- buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff/CharProcs get begin/")
- << ps_glyphindex << FX_BSTRC("{");
- buf << FX_BSTRC("n ");
- for (int p = 0; p < TransformedPath.GetPointCount(); p ++) {
- FX_FLOAT x = TransformedPath.GetPointX(p), y = TransformedPath.GetPointY(p);
- switch (TransformedPath.GetFlag(p) & FXPT_TYPE) {
- case FXPT_MOVETO: {
- buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" m\n");
- break;
- }
- case FXPT_LINETO: {
- buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" l\n");
- break;
- }
- case FXPT_BEZIERTO: {
- buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" ")
- << TransformedPath.GetPointX(p + 1) << FX_BSTRC(" ")
- << TransformedPath.GetPointY(p + 1) << FX_BSTRC(" ")
- << TransformedPath.GetPointX(p + 2) << FX_BSTRC(" ")
- << TransformedPath.GetPointY(p + 2) << FX_BSTRC(" c\n");
- p += 2;
- break;
- }
- }
- }
- buf << FX_BSTRC("f");
- buf << FX_BSTRC("}bind def end\n");
- buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff/Encoding get ") << ps_glyphindex
- << FX_BSTRC("/") << ps_glyphindex << FX_BSTRC(" put\n");
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
-}
-FX_BOOL CFX_PSRenderer::DrawText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
- CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device,
- FX_FLOAT font_size, FX_DWORD color,
- int alpha_flag, void* pIccTransform)
-{
- StartRendering();
- int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
- if (alpha < 255) {
- return FALSE;
- }
- if ((pObject2Device->a == 0 && pObject2Device->b == 0) || (pObject2Device->c == 0 && pObject2Device->d == 0)) {
- return TRUE;
- }
- SetColor(color, alpha_flag, pIccTransform);
- CFX_ByteTextBuf buf;
- buf << FX_BSTRC("q[") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ")
- << pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d;
- buf << FX_BSTRC(" ") << pObject2Device->e << FX_BSTRC(" ") << pObject2Device->f << "]cm\n";
- if (pCache == NULL) {
- pCache = CFX_GEModule::Get()->GetFontCache();
- }
- CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
- FX_FONTCACHE_DEFINE(pCache, pFont);
- int last_fontnum = -1;
- for (int i = 0; i < nChars; i ++) {
- int ps_fontnum, ps_glyphindex;
- FindPSFontGlyph(pFaceCache, pFont, pCharPos[i], ps_fontnum, ps_glyphindex);
- if (last_fontnum != ps_fontnum) {
- buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff ") << font_size
- << FX_BSTRC(" Fs Sf ");
- last_fontnum = ps_fontnum;
- }
- buf << pCharPos[i].m_OriginX << FX_BSTRC(" ")
- << pCharPos[i].m_OriginY << FX_BSTRC(" m");
- CFX_ByteString hex;
- hex.Format("<%02X>", ps_glyphindex);
- buf << hex << FX_BSTRC("Tj\n");
- }
- buf << FX_BSTRC("Q\n");
- m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
- return TRUE;
-}
-void CFX_PSRenderer::WritePSBinary(FX_LPCBYTE data, int len)
-{
- FX_LPBYTE dest_buf;
- FX_DWORD dest_size;
- CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
- if (pEncoders && pEncoders->GetBasicModule()->A85Encode(data, len, dest_buf, dest_size)) {
- m_pOutput->OutputPS((FX_LPCSTR)dest_buf, dest_size);
- FX_Free(dest_buf);
- } else {
- m_pOutput->OutputPS((FX_LPCSTR)data, len);
- }
-}
+// 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 "../../../include/fxge/fx_ge.h"
+#include "../../../include/fxcodec/fx_codec.h"
+#include "text_int.h"
+struct PSGlyph {
+ CFX_Font* m_pFont;
+ FX_DWORD m_GlyphIndex;
+ FX_BOOL m_bGlyphAdjust;
+ FX_FLOAT m_AdjustMatrix[4];
+};
+class CPSFont : public CFX_Object
+{
+public:
+ PSGlyph m_Glyphs[256];
+ int m_nGlyphs;
+};
+CFX_PSRenderer::CFX_PSRenderer()
+{
+ m_pOutput = NULL;
+ m_bColorSet = m_bGraphStateSet = FALSE;
+ m_bInited = FALSE;
+}
+CFX_PSRenderer::~CFX_PSRenderer()
+{
+ for (int i = 0; i < (int)m_PSFontList.GetSize(); i ++) {
+ CPSFont* pFont = m_PSFontList[i];
+ delete pFont;
+ }
+}
+#define OUTPUT_PS(str) m_pOutput->OutputPS(str, sizeof str-1)
+void CFX_PSRenderer::Init(IFX_PSOutput* pOutput, int pslevel, int width, int height, FX_BOOL bCmykOutput)
+{
+ m_PSLevel = pslevel;
+ m_pOutput = pOutput;
+ m_ClipBox.left = m_ClipBox.top = 0;
+ m_ClipBox.right = width;
+ m_ClipBox.bottom = height;
+ m_bCmykOutput = bCmykOutput;
+}
+FX_BOOL CFX_PSRenderer::StartRendering()
+{
+ if (m_bInited) {
+ return TRUE;
+ }
+ static const char init_str[] = "\nsave\n/im/initmatrix load def\n"
+ "/n/newpath load def/m/moveto load def/l/lineto load def/c/curveto load def/h/closepath load def\n"
+ "/f/fill load def/F/eofill load def/s/stroke load def/W/clip load def/W*/eoclip load def\n"
+ "/rg/setrgbcolor load def/k/setcmykcolor load def\n"
+ "/J/setlinecap load def/j/setlinejoin load def/w/setlinewidth load def/M/setmiterlimit load def/d/setdash load def\n"
+ "/q/gsave load def/Q/grestore load def/iM/imagemask load def\n"
+ "/Tj/show load def/Ff/findfont load def/Fs/scalefont load def/Sf/setfont load def\n"
+ "/cm/concat load def/Cm/currentmatrix load def/mx/matrix load def/sm/setmatrix load def\n"
+ ;
+ OUTPUT_PS(init_str);
+ m_bInited = TRUE;
+ return TRUE;
+}
+void CFX_PSRenderer::EndRendering()
+{
+ if (m_bInited) {
+ OUTPUT_PS("\nrestore\n");
+ }
+ m_bInited = FALSE;
+}
+void CFX_PSRenderer::SaveState()
+{
+ StartRendering();
+ OUTPUT_PS("q\n");
+ m_ClipBoxStack.Add(m_ClipBox);
+}
+void CFX_PSRenderer::RestoreState(FX_BOOL bKeepSaved)
+{
+ StartRendering();
+ if (bKeepSaved) {
+ OUTPUT_PS("Q\nq\n");
+ } else {
+ OUTPUT_PS("Q\n");
+ }
+ m_bColorSet = m_bGraphStateSet = FALSE;
+ m_ClipBox = m_ClipBoxStack.GetAt(m_ClipBoxStack.GetSize() - 1);
+ if (!bKeepSaved) {
+ m_ClipBoxStack.RemoveAt(m_ClipBoxStack.GetSize() - 1);
+ }
+}
+void CFX_PSRenderer::OutputPath(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device)
+{
+ int nPoints = pPathData->GetPointCount();
+ CFX_ByteTextBuf buf;
+ buf.EstimateSize(nPoints * 10);
+ for (int i = 0; i < nPoints; i ++) {
+ FX_BYTE flag = pPathData->GetFlag(i);
+ FX_FLOAT x = pPathData->GetPointX(i);
+ FX_FLOAT y = pPathData->GetPointY(i);
+ if (pObject2Device) {
+ pObject2Device->Transform(x, y);
+ }
+ buf << x << FX_BSTRC(" ") << y;
+ switch (flag & FXPT_TYPE) {
+ case FXPT_MOVETO:
+ buf << FX_BSTRC(" m ");
+ break;
+ case FXPT_LINETO:
+ if (flag & FXPT_CLOSEFIGURE) {
+ buf << FX_BSTRC(" l h ");
+ } else {
+ buf << FX_BSTRC(" l ");
+ }
+ break;
+ case FXPT_BEZIERTO: {
+ FX_FLOAT x1 = pPathData->GetPointX(i + 1);
+ FX_FLOAT x2 = pPathData->GetPointX(i + 2);
+ FX_FLOAT y1 = pPathData->GetPointY(i + 1);
+ FX_FLOAT y2 = pPathData->GetPointY(i + 2);
+ if (pObject2Device) {
+ pObject2Device->Transform(x1, y1);
+ pObject2Device->Transform(x2, y2);
+ }
+ buf << FX_BSTRC(" ") << x1 << FX_BSTRC(" ") << y1 << FX_BSTRC(" ") << x2 << FX_BSTRC(" ") << y2;
+ if (flag & FXPT_CLOSEFIGURE) {
+ buf << FX_BSTRC(" c h\n");
+ } else {
+ buf << FX_BSTRC(" c\n");
+ }
+ i += 2;
+ break;
+ }
+ }
+ }
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+}
+void CFX_PSRenderer::SetClip_PathFill(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ int fill_mode
+ )
+{
+ StartRendering();
+ OutputPath(pPathData, pObject2Device);
+ CFX_FloatRect rect = pPathData->GetBoundingBox();
+ if (pObject2Device) {
+ rect.Transform(pObject2Device);
+ }
+ m_ClipBox.Intersect(rect.GetOutterRect());
+ if ((fill_mode & 3) == FXFILL_WINDING) {
+ OUTPUT_PS("W n\n");
+ } else {
+ OUTPUT_PS("W* n\n");
+ }
+}
+void CFX_PSRenderer::SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState
+ )
+{
+ StartRendering();
+ SetGraphState(pGraphState);
+ if (pObject2Device) {
+ CFX_ByteTextBuf buf;
+ buf << FX_BSTRC("mx Cm [") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ") <<
+ pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d << FX_BSTRC(" ") << pObject2Device->e <<
+ FX_BSTRC(" ") << pObject2Device->f << FX_BSTRC("]cm ");
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+ }
+ OutputPath(pPathData, NULL);
+ CFX_FloatRect rect = pPathData->GetBoundingBox(pGraphState->m_LineWidth, pGraphState->m_MiterLimit);
+ rect.Transform(pObject2Device);
+ m_ClipBox.Intersect(rect.GetOutterRect());
+ if (pObject2Device) {
+ OUTPUT_PS("strokepath W n sm\n");
+ } else {
+ OUTPUT_PS("strokepath W n\n");
+ }
+}
+FX_BOOL CFX_PSRenderer::DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag,
+ void* pIccTransform
+ )
+{
+ StartRendering();
+ int fill_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(fill_color);
+ int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_STROKE(alpha_flag) : FXARGB_A(stroke_color);
+ if (fill_alpha && fill_alpha < 255) {
+ return FALSE;
+ }
+ if (stroke_alpha && stroke_alpha < 255) {
+ return FALSE;
+ }
+ if (fill_alpha == 0 && stroke_alpha == 0) {
+ return FALSE;
+ }
+ if (stroke_alpha) {
+ SetGraphState(pGraphState);
+ if (pObject2Device) {
+ CFX_ByteTextBuf buf;
+ buf << FX_BSTRC("mx Cm [") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ") <<
+ pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d << FX_BSTRC(" ") << pObject2Device->e <<
+ FX_BSTRC(" ") << pObject2Device->f << FX_BSTRC("]cm ");
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+ }
+ }
+ OutputPath(pPathData, stroke_alpha ? NULL : pObject2Device);
+ if (fill_mode && fill_alpha) {
+ SetColor(fill_color, alpha_flag, pIccTransform);
+ if ((fill_mode & 3) == FXFILL_WINDING) {
+ if (stroke_alpha) {
+ OUTPUT_PS("q f Q ");
+ } else {
+ OUTPUT_PS("f");
+ }
+ } else if ((fill_mode & 3) == FXFILL_ALTERNATE) {
+ if (stroke_alpha) {
+ OUTPUT_PS("q F Q ");
+ } else {
+ OUTPUT_PS("F");
+ }
+ }
+ }
+ if (stroke_alpha) {
+ SetColor(stroke_color, alpha_flag, pIccTransform);
+ if (pObject2Device) {
+ OUTPUT_PS("s sm");
+ } else {
+ OUTPUT_PS("s");
+ }
+ }
+ OUTPUT_PS("\n");
+ return TRUE;
+}
+void CFX_PSRenderer::SetGraphState(const CFX_GraphStateData* pGraphState)
+{
+ CFX_ByteTextBuf buf;
+ if (!m_bGraphStateSet || m_CurGraphState.m_LineCap != pGraphState->m_LineCap) {
+ buf << pGraphState->m_LineCap << FX_BSTRC(" J\n");
+ }
+ if (!m_bGraphStateSet || m_CurGraphState.m_DashCount != pGraphState->m_DashCount ||
+ FXSYS_memcmp32(m_CurGraphState.m_DashArray, pGraphState->m_DashArray, sizeof(FX_FLOAT)*m_CurGraphState.m_DashCount)) {
+ buf << FX_BSTRC("[");
+ for (int i = 0; i < pGraphState->m_DashCount; i ++) {
+ buf << pGraphState->m_DashArray[i] << FX_BSTRC(" ");
+ }
+ buf << FX_BSTRC("]") << pGraphState->m_DashPhase << FX_BSTRC(" d\n");
+ }
+ if (!m_bGraphStateSet || m_CurGraphState.m_LineJoin != pGraphState->m_LineJoin) {
+ buf << pGraphState->m_LineJoin << FX_BSTRC(" j\n");
+ }
+ if (!m_bGraphStateSet || m_CurGraphState.m_LineWidth != pGraphState->m_LineWidth) {
+ buf << pGraphState->m_LineWidth << FX_BSTRC(" w\n");
+ }
+ if (!m_bGraphStateSet || m_CurGraphState.m_MiterLimit != pGraphState->m_MiterLimit) {
+ buf << pGraphState->m_MiterLimit << FX_BSTRC(" M\n");
+ }
+ m_CurGraphState.Copy(*pGraphState);
+ m_bGraphStateSet = TRUE;
+ if (buf.GetSize()) {
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+ }
+}
+static void FaxCompressData(FX_LPBYTE src_buf, int width, int height, FX_LPBYTE& dest_buf, FX_DWORD& dest_size)
+{
+ CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
+ if (width * height > 128 && pEncoders && pEncoders->GetFaxModule()->Encode(src_buf, width, height, (width + 7) / 8, dest_buf, dest_size)) {
+ FX_Free(src_buf);
+ } else {
+ dest_buf = src_buf;
+ dest_size = (width + 7) / 8 * height;
+ }
+}
+static void PSCompressData(int PSLevel, FX_LPBYTE src_buf, FX_DWORD src_size,
+ FX_LPBYTE& output_buf, FX_DWORD& output_size, FX_LPCSTR& filter)
+{
+ output_buf = src_buf;
+ output_size = src_size;
+ filter = "";
+ if (src_size < 1024) {
+ return;
+ }
+ CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
+ FX_LPBYTE dest_buf = NULL;
+ FX_DWORD dest_size = src_size;
+ if (PSLevel >= 3) {
+ if (pEncoders && pEncoders->GetFlateModule()->Encode(src_buf, src_size, dest_buf, dest_size)) {
+ filter = "/FlateDecode filter ";
+ }
+ } else {
+ if (pEncoders && pEncoders->GetBasicModule()->RunLengthEncode(src_buf, src_size, dest_buf, dest_size)) {
+ filter = "/RunLengthDecode filter ";
+ }
+ }
+ if (dest_size < src_size) {
+ output_buf = dest_buf;
+ output_size = dest_size;
+ } else {
+ filter = NULL;
+ if (dest_buf) {
+ FX_Free(dest_buf);
+ }
+ }
+}
+FX_BOOL CFX_PSRenderer::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int left, int top,
+ int alpha_flag, void* pIccTransform)
+{
+ StartRendering();
+ CFX_AffineMatrix matrix((FX_FLOAT)(pSource->GetWidth()), 0.0f, 0.0f, -(FX_FLOAT)(pSource->GetHeight()),
+ (FX_FLOAT)(left), (FX_FLOAT)(top + pSource->GetHeight()));
+ return DrawDIBits(pSource, color, &matrix, 0, alpha_flag, pIccTransform);
+}
+FX_BOOL CFX_PSRenderer::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform)
+{
+ StartRendering();
+ CFX_AffineMatrix matrix((FX_FLOAT)(dest_width), 0.0f, 0.0f, (FX_FLOAT)(-dest_height),
+ (FX_FLOAT)(dest_left), (FX_FLOAT)(dest_top + dest_height));
+ return DrawDIBits(pSource, color, &matrix, flags, alpha_flag, pIccTransform);
+}
+FX_BOOL CFX_PSRenderer::DrawDIBits(const CFX_DIBSource* pSource, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform)
+{
+ StartRendering();
+ if ((pMatrix->a == 0 && pMatrix->b == 0) || (pMatrix->c == 0 && pMatrix->d == 0)) {
+ return TRUE;
+ }
+ if (pSource->HasAlpha()) {
+ return FALSE;
+ }
+ int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(color) : FXARGB_A(color);
+ if (pSource->IsAlphaMask() && (alpha < 255 || pSource->GetBPP() != 1)) {
+ return FALSE;
+ }
+ OUTPUT_PS("q\n");
+ CFX_ByteTextBuf buf;
+ buf << FX_BSTRC("[") << pMatrix->a << FX_BSTRC(" ") << pMatrix->b << FX_BSTRC(" ") <<
+ pMatrix->c << FX_BSTRC(" ") << pMatrix->d << FX_BSTRC(" ") << pMatrix->e <<
+ FX_BSTRC(" ") << pMatrix->f << FX_BSTRC("]cm ");
+ int width = pSource->GetWidth();
+ int height = pSource->GetHeight();
+ buf << width << FX_BSTRC(" ") << height;
+ if (pSource->GetBPP() == 1 && pSource->GetPalette() == NULL) {
+ int pitch = (width + 7) / 8;
+ FX_DWORD src_size = height * pitch;
+ FX_LPBYTE src_buf = FX_Alloc(FX_BYTE, src_size);
+ if (!src_buf) {
+ return FALSE;
+ }
+ for (int row = 0; row < height; row ++) {
+ FX_LPCBYTE src_scan = pSource->GetScanline(row);
+ FXSYS_memcpy32(src_buf + row * pitch, src_scan, pitch);
+ }
+ FX_LPBYTE output_buf;
+ FX_DWORD output_size;
+ FaxCompressData(src_buf, width, height, output_buf, output_size);
+ if (pSource->IsAlphaMask()) {
+ SetColor(color, alpha_flag, pIccTransform);
+ m_bColorSet = FALSE;
+ buf << FX_BSTRC(" true[");
+ } else {
+ buf << FX_BSTRC(" 1[");
+ }
+ buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height <<
+ FX_BSTRC("]currentfile/ASCII85Decode filter ");
+ if (output_buf != src_buf)
+ buf << FX_BSTRC("<</K -1/EndOfBlock false/Columns ") << width << FX_BSTRC("/Rows ") << height <<
+ FX_BSTRC(">>/CCITTFaxDecode filter ");
+ if (pSource->IsAlphaMask()) {
+ buf << FX_BSTRC("iM\n");
+ } else {
+ buf << FX_BSTRC("false 1 colorimage\n");
+ }
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+ WritePSBinary(output_buf, output_size);
+ FX_Free(output_buf);
+ } else {
+ CFX_DIBSource* pConverted = (CFX_DIBSource*)pSource;
+ if (pIccTransform) {
+ FXDIB_Format format = m_bCmykOutput ? FXDIB_Cmyk : FXDIB_Rgb;
+ pConverted = pSource->CloneConvert(format, NULL, pIccTransform);
+ } else {
+ switch (pSource->GetFormat()) {
+ case FXDIB_1bppRgb:
+ case FXDIB_Rgb32:
+ pConverted = pSource->CloneConvert(FXDIB_Rgb);
+ break;
+ case FXDIB_8bppRgb:
+ if (pSource->GetPalette() != NULL) {
+ pConverted = pSource->CloneConvert(FXDIB_Rgb);
+ }
+ break;
+ case FXDIB_1bppCmyk:
+ pConverted = pSource->CloneConvert(FXDIB_Cmyk);
+ break;
+ case FXDIB_8bppCmyk:
+ if (pSource->GetPalette() != NULL) {
+ pConverted = pSource->CloneConvert(FXDIB_Cmyk);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if (pConverted == NULL) {
+ OUTPUT_PS("\nQ\n");
+ return FALSE;
+ }
+ int Bpp = pConverted->GetBPP() / 8;
+ FX_LPBYTE output_buf = NULL;
+ FX_STRSIZE output_size = 0;
+ FX_LPCSTR filter = NULL;
+ if (flags & FXRENDER_IMAGE_LOSSY) {
+ CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
+ if (pEncoders && pEncoders->GetJpegModule()->Encode(pConverted, output_buf, output_size)) {
+ filter = "/DCTDecode filter ";
+ }
+ }
+ if (filter == NULL) {
+ int src_pitch = width * Bpp;
+ output_size = height * src_pitch;
+ output_buf = FX_Alloc(FX_BYTE, output_size);
+ if (!output_buf) {
+ if (pConverted != pSource) {
+ delete pConverted;
+ pConverted = NULL;
+ }
+ return FALSE;
+ }
+ for (int row = 0; row < height; row ++) {
+ FX_LPCBYTE src_scan = pConverted->GetScanline(row);
+ FX_LPBYTE dest_scan = output_buf + row * src_pitch;
+ if (Bpp == 3) {
+ for (int col = 0; col < width; col ++) {
+ *dest_scan++ = src_scan[2];
+ *dest_scan++ = src_scan[1];
+ *dest_scan++ = *src_scan;
+ src_scan += 3;
+ }
+ } else {
+ FXSYS_memcpy32(dest_scan, src_scan, src_pitch);
+ }
+ }
+ FX_LPBYTE compressed_buf;
+ FX_DWORD compressed_size;
+ PSCompressData(m_PSLevel, output_buf, output_size, compressed_buf, compressed_size, filter);
+ if (output_buf != compressed_buf) {
+ FX_Free(output_buf);
+ }
+ output_buf = compressed_buf;
+ output_size = compressed_size;
+ }
+ if (pConverted != pSource) {
+ delete pConverted;
+ pConverted = NULL;
+ }
+ buf << FX_BSTRC(" 8[");
+ buf << width << FX_BSTRC(" 0 0 -") << height << FX_BSTRC(" 0 ") << height << FX_BSTRC("]");
+ buf << FX_BSTRC("currentfile/ASCII85Decode filter ");
+ if (filter) {
+ buf << filter;
+ }
+ buf << FX_BSTRC("false ") << Bpp;
+ buf << FX_BSTRC(" colorimage\n");
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+ WritePSBinary(output_buf, output_size);
+ FX_Free(output_buf);
+ }
+ OUTPUT_PS("\nQ\n");
+ return TRUE;
+}
+void CFX_PSRenderer::SetColor(FX_DWORD color, int alpha_flag, void* pIccTransform)
+{
+ if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
+ pIccTransform = NULL;
+ }
+ FX_BOOL bCMYK = FALSE;
+ if (pIccTransform) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
+ FX_LPBYTE pColor = (FX_LPBYTE)&color;
+ pIccModule->TranslateScanline(pIccTransform, pColor, pColor, 1);
+ color = m_bCmykOutput ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
+ bCMYK = m_bCmykOutput;
+ } else {
+ bCMYK = FXGETFLAG_COLORTYPE(alpha_flag);
+ }
+ if (bCMYK != m_bCmykOutput || !m_bColorSet || m_LastColor != color) {
+ CFX_ByteTextBuf buf;
+ if (bCMYK) {
+ buf << FXSYS_GetCValue(color) / 255.0 << FX_BSTRC(" ") << FXSYS_GetMValue(color) / 255.0 << FX_BSTRC(" ")
+ << FXSYS_GetYValue(color) / 255.0 << FX_BSTRC(" ") << FXSYS_GetKValue(color) / 255.0 << FX_BSTRC(" k\n");
+ } else {
+ buf << FXARGB_R(color) / 255.0 << FX_BSTRC(" ") << FXARGB_G(color) / 255.0 << FX_BSTRC(" ")
+ << FXARGB_B(color) / 255.0 << FX_BSTRC(" rg\n");
+ }
+ if (bCMYK == m_bCmykOutput) {
+ m_bColorSet = TRUE;
+ m_LastColor = color;
+ }
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+ }
+}
+void CFX_PSRenderer::FindPSFontGlyph(CFX_FaceCache* pFaceCache, CFX_Font* pFont, const FXTEXT_CHARPOS& charpos,
+ int& ps_fontnum, int &ps_glyphindex)
+{
+ for (int i = 0; i < (int)m_PSFontList.GetSize(); i ++) {
+ CPSFont* pPSFont = m_PSFontList[i];
+ for (int j = 0; j < pPSFont->m_nGlyphs; j ++)
+ if (pPSFont->m_Glyphs[j].m_pFont == pFont && pPSFont->m_Glyphs[j].m_GlyphIndex == charpos.m_GlyphIndex) {
+ if ((!pPSFont->m_Glyphs[j].m_bGlyphAdjust && !charpos.m_bGlyphAdjust) ||
+ (pPSFont->m_Glyphs[j].m_bGlyphAdjust && charpos.m_bGlyphAdjust &&
+ (FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[0] - charpos.m_AdjustMatrix[0]) < 0.01 &&
+ FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[1] - charpos.m_AdjustMatrix[1]) < 0.01 &&
+ FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[2] - charpos.m_AdjustMatrix[2]) < 0.01 &&
+ FXSYS_fabs(pPSFont->m_Glyphs[j].m_AdjustMatrix[3] - charpos.m_AdjustMatrix[3]) < 0.01))) {
+ ps_fontnum = i;
+ ps_glyphindex = j;
+ return;
+ }
+ }
+ }
+ if (m_PSFontList.GetSize() == 0 || m_PSFontList[m_PSFontList.GetSize() - 1]->m_nGlyphs == 256) {
+ CPSFont* pPSFont = FX_NEW CPSFont;
+ if (!pPSFont) {
+ return;
+ }
+ pPSFont->m_nGlyphs = 0;
+ m_PSFontList.Add(pPSFont);
+ CFX_ByteTextBuf buf;
+ buf << FX_BSTRC("8 dict begin/FontType 3 def/FontMatrix[1 0 0 1 0 0]def\n"
+ "/FontBBox[0 0 0 0]def/Encoding 256 array def 0 1 255{Encoding exch/.notdef put}for\n"
+ "/CharProcs 1 dict def CharProcs begin/.notdef {} def end\n"
+ "/BuildGlyph{1 0 -10 -10 10 10 setcachedevice exch/CharProcs get exch 2 copy known not{pop/.notdef}if get exec}bind def\n"
+ "/BuildChar{1 index/Encoding get exch get 1 index/BuildGlyph get exec}bind def\n"
+ "currentdict end\n");
+ buf << FX_BSTRC("/X") << m_PSFontList.GetSize() - 1 << FX_BSTRC(" exch definefont pop\n");
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+ buf.Clear();
+ }
+ ps_fontnum = m_PSFontList.GetSize() - 1;
+ CPSFont* pPSFont = m_PSFontList[ps_fontnum];
+ ps_glyphindex = pPSFont->m_nGlyphs;
+ pPSFont->m_Glyphs[ps_glyphindex].m_GlyphIndex = charpos.m_GlyphIndex;
+ pPSFont->m_Glyphs[ps_glyphindex].m_pFont = pFont;
+ pPSFont->m_Glyphs[ps_glyphindex].m_bGlyphAdjust = charpos.m_bGlyphAdjust;
+ if (charpos.m_bGlyphAdjust) {
+ pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[0] = charpos.m_AdjustMatrix[0];
+ pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[1] = charpos.m_AdjustMatrix[1];
+ pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[2] = charpos.m_AdjustMatrix[2];
+ pPSFont->m_Glyphs[ps_glyphindex].m_AdjustMatrix[3] = charpos.m_AdjustMatrix[3];
+ }
+ pPSFont->m_nGlyphs ++;
+ CFX_AffineMatrix matrix;
+ if (charpos.m_bGlyphAdjust)
+ matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1],
+ charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0);
+ matrix.Concat(1.0f, 0, 0, 1.0f, 0, 0);
+ const CFX_PathData* pPathData = pFaceCache->LoadGlyphPath(pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth);
+ if (pPathData == NULL) {
+ return;
+ }
+ CFX_PathData TransformedPath(*pPathData);
+ if (charpos.m_bGlyphAdjust) {
+ TransformedPath.Transform(&matrix);
+ }
+ CFX_ByteTextBuf buf;
+ buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff/CharProcs get begin/")
+ << ps_glyphindex << FX_BSTRC("{");
+ buf << FX_BSTRC("n ");
+ for (int p = 0; p < TransformedPath.GetPointCount(); p ++) {
+ FX_FLOAT x = TransformedPath.GetPointX(p), y = TransformedPath.GetPointY(p);
+ switch (TransformedPath.GetFlag(p) & FXPT_TYPE) {
+ case FXPT_MOVETO: {
+ buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" m\n");
+ break;
+ }
+ case FXPT_LINETO: {
+ buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" l\n");
+ break;
+ }
+ case FXPT_BEZIERTO: {
+ buf << x << FX_BSTRC(" ") << y << FX_BSTRC(" ")
+ << TransformedPath.GetPointX(p + 1) << FX_BSTRC(" ")
+ << TransformedPath.GetPointY(p + 1) << FX_BSTRC(" ")
+ << TransformedPath.GetPointX(p + 2) << FX_BSTRC(" ")
+ << TransformedPath.GetPointY(p + 2) << FX_BSTRC(" c\n");
+ p += 2;
+ break;
+ }
+ }
+ }
+ buf << FX_BSTRC("f");
+ buf << FX_BSTRC("}bind def end\n");
+ buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff/Encoding get ") << ps_glyphindex
+ << FX_BSTRC("/") << ps_glyphindex << FX_BSTRC(" put\n");
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+}
+FX_BOOL CFX_PSRenderer::DrawText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
+ CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device,
+ FX_FLOAT font_size, FX_DWORD color,
+ int alpha_flag, void* pIccTransform)
+{
+ StartRendering();
+ int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
+ if (alpha < 255) {
+ return FALSE;
+ }
+ if ((pObject2Device->a == 0 && pObject2Device->b == 0) || (pObject2Device->c == 0 && pObject2Device->d == 0)) {
+ return TRUE;
+ }
+ SetColor(color, alpha_flag, pIccTransform);
+ CFX_ByteTextBuf buf;
+ buf << FX_BSTRC("q[") << pObject2Device->a << FX_BSTRC(" ") << pObject2Device->b << FX_BSTRC(" ")
+ << pObject2Device->c << FX_BSTRC(" ") << pObject2Device->d;
+ buf << FX_BSTRC(" ") << pObject2Device->e << FX_BSTRC(" ") << pObject2Device->f << "]cm\n";
+ if (pCache == NULL) {
+ pCache = CFX_GEModule::Get()->GetFontCache();
+ }
+ CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
+ FX_FONTCACHE_DEFINE(pCache, pFont);
+ int last_fontnum = -1;
+ for (int i = 0; i < nChars; i ++) {
+ int ps_fontnum, ps_glyphindex;
+ FindPSFontGlyph(pFaceCache, pFont, pCharPos[i], ps_fontnum, ps_glyphindex);
+ if (last_fontnum != ps_fontnum) {
+ buf << FX_BSTRC("/X") << ps_fontnum << FX_BSTRC(" Ff ") << font_size
+ << FX_BSTRC(" Fs Sf ");
+ last_fontnum = ps_fontnum;
+ }
+ buf << pCharPos[i].m_OriginX << FX_BSTRC(" ")
+ << pCharPos[i].m_OriginY << FX_BSTRC(" m");
+ CFX_ByteString hex;
+ hex.Format("<%02X>", ps_glyphindex);
+ buf << hex << FX_BSTRC("Tj\n");
+ }
+ buf << FX_BSTRC("Q\n");
+ m_pOutput->OutputPS((FX_LPCSTR)buf.GetBuffer(), buf.GetSize());
+ return TRUE;
+}
+void CFX_PSRenderer::WritePSBinary(FX_LPCBYTE data, int len)
+{
+ FX_LPBYTE dest_buf;
+ FX_DWORD dest_size;
+ CCodec_ModuleMgr* pEncoders = CFX_GEModule::Get()->GetCodecModule();
+ if (pEncoders && pEncoders->GetBasicModule()->A85Encode(data, len, dest_buf, dest_size)) {
+ m_pOutput->OutputPS((FX_LPCSTR)dest_buf, dest_size);
+ FX_Free(dest_buf);
+ } else {
+ m_pOutput->OutputPS((FX_LPCSTR)data, len);
+ }
+}
diff --git a/core/src/fxge/ge/fx_ge_text.cpp b/core/src/fxge/ge/fx_ge_text.cpp
index 92f631e615..40acc5fe34 100644
--- a/core/src/fxge/ge/fx_ge_text.cpp
+++ b/core/src/fxge/ge/fx_ge_text.cpp
@@ -1,1774 +1,1774 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#include "../../../include/fxge/fx_freetype.h"
-#include "../../../include/fxcodec/fx_codec.h"
-#include "text_int.h"
-#undef FX_GAMMA
-#undef FX_GAMMA_INVERSE
-#define FX_GAMMA(value) (value)
-#define FX_GAMMA_INVERSE(value) (value)
-FX_RECT FXGE_GetGlyphsBBox(FXTEXT_GLYPHPOS* pGlyphAndPos, int nChars, int anti_alias, FX_FLOAT retinaScaleX, FX_FLOAT retinaScaleY)
-{
- FX_RECT rect(0, 0, 0, 0);
- FX_BOOL bStarted = FALSE;
- for (int iChar = 0; iChar < nChars; iChar ++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
- const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph;
- if (pGlyph == NULL) {
- continue;
- }
- int char_left = glyph.m_OriginX + pGlyph->m_Left;
- int char_width = (int)(pGlyph->m_Bitmap.GetWidth() / retinaScaleX);
- if (anti_alias == FXFT_RENDER_MODE_LCD) {
- char_width /= 3;
- }
- int char_right = char_left + char_width;
- int char_top = glyph.m_OriginY - pGlyph->m_Top;
- int char_bottom = char_top + (int)(pGlyph->m_Bitmap.GetHeight() / retinaScaleY);
- if (!bStarted) {
- rect.left = char_left;
- rect.right = char_right;
- rect.top = char_top;
- rect.bottom = char_bottom;
- bStarted = TRUE;
- } else {
- if (rect.left > char_left) {
- rect.left = char_left;
- }
- if (rect.right < char_right) {
- rect.right = char_right;
- }
- if (rect.top > char_top) {
- rect.top = char_top;
- }
- if (rect.bottom < char_bottom) {
- rect.bottom = char_bottom;
- }
- }
- }
- return rect;
-}
-static void _AdjustGlyphSpace(FXTEXT_GLYPHPOS* pGlyphAndPos, int nChars)
-{
- ASSERT(nChars > 1);
- FX_BOOL bVertical = FALSE;
- if (pGlyphAndPos[nChars - 1].m_OriginX == pGlyphAndPos[0].m_OriginX) {
- bVertical = TRUE;
- } else if (pGlyphAndPos[nChars - 1].m_OriginY != pGlyphAndPos[0].m_OriginY) {
- return;
- }
- int i = nChars - 1;
- int* next_origin = bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPos[i].m_OriginX;
- FX_FLOAT next_origin_f = bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyphAndPos[i].m_fOriginX;
- for (i --; i > 0; i --) {
- int* this_origin = bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPos[i].m_OriginX;
- FX_FLOAT this_origin_f = bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyphAndPos[i].m_fOriginX;
- int space = (*next_origin) - (*this_origin);
- FX_FLOAT space_f = next_origin_f - this_origin_f;
- FX_FLOAT error = (FX_FLOAT)(FXSYS_fabs(space_f) - FXSYS_fabs((FX_FLOAT)(space)));
- if (error > 0.5f) {
- *this_origin += space > 0 ? -1 : 1;
- }
- next_origin = this_origin;
- next_origin_f = this_origin_f;
- }
-}
-static const FX_BYTE g_GdipGamma_bgw[9] = {0, 0, 63, 120, 0, 168, 210, 239, 255};
-static const FX_BYTE g_GdipGamma_fgw[9] = {0, 0, 16, 45, 0, 87, 135, 192, 255};
-static const FX_BYTE g_GdipGammaAdjust_47[48] = {
- 0, 30, 33, 34, 35, 36, 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 43,
- 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 46,
- 46, 46, 46, 46, 46, 46, 46, 47
-};
-static const FX_BYTE g_GdipGammaAdjust_75[76] = {
- 0, 46, 50, 52, 54, 55, 56, 57, 58, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 64, 65,
- 65, 65, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 70, 70, 70,
- 70, 70, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73,
- 73, 74, 74, 74, 74, 74, 74, 74, 74, 75
-};
-static const FX_BYTE g_GdipGammaAdjust_81[82] = {
- 0, 49, 53, 56, 58, 59, 60, 61, 62, 63, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 69, 70, 70, 70,
- 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 76,
- 76, 76, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 80,
- 80, 80, 80, 80, 80, 80, 80, 81
-};
-static void _Adjust_alpha(int background, int foreground, int& src_alpha, int text_flags, int a)
-{
-}
-static const FX_BYTE g_TextGammaAdjust[256] = {
- 0, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 19,
- 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 38,
- 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55,
- 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72,
- 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
- 121, 122, 123, 124, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134, 135,
- 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
- 152, 153, 154, 155, 156, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
- 167, 168, 169, 170, 171, 172, 173, 174, 174, 175, 176, 177, 178, 179, 180, 181,
- 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196,
- 197, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 210, 211,
- 212, 213, 214, 215, 216, 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
- 227, 228, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 239, 240,
- 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 250, 251, 252, 253, 254, 255,
-};
-#define ADJUST_ALPHA(background, foreground, src_alpha, text_flags, a) \
- src_alpha = g_TextGammaAdjust[(FX_BYTE)src_alpha];
-void _Color2Argb(FX_ARGB& argb, FX_DWORD color, int alpha_flag, void* pIccTransform)
-{
- if (pIccTransform == NULL && !FXGETFLAG_COLORTYPE(alpha_flag)) {
- argb = color;
- return;
- }
- if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
- pIccTransform = NULL;
- }
- FX_BYTE bgra[4];
- if (pIccTransform) {
- ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
- color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
- pIccModule->TranslateScanline(pIccTransform, bgra, (FX_LPCBYTE)&color, 1);
- bgra[3] = FXGETFLAG_COLORTYPE(alpha_flag) ?
- (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXGETFLAG_ALPHA_STROKE(alpha_flag) :
- FXARGB_A(color);
- argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]);
- return;
- }
- AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color),
- FXSYS_GetYValue(color), FXSYS_GetKValue(color),
- bgra[2], bgra[1], bgra[0]);
- bgra[3] = (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXGETFLAG_ALPHA_STROKE(alpha_flag);
- argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]);
-}
-FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars, const FXTEXT_CHARPOS* pCharPos,
- CFX_Font* pFont, CFX_FontCache* pCache,
- FX_FLOAT font_size, const CFX_AffineMatrix* pText2Device,
- FX_DWORD fill_color, FX_DWORD text_flags,
- int alpha_flag, void* pIccTransform)
-{
- int nativetext_flags = text_flags;
- if (m_DeviceClass != FXDC_DISPLAY) {
- if (!(text_flags & FXTEXT_PRINTGRAPHICTEXT)) {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!(text_flags & FXFONT_CIDFONT) && pFont->GetPsName().Find(CFX_WideString::FromLocal("+ZJHL")) == -1)
-#ifdef FOXIT_CHROME_BUILD
- if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10"))
-#endif
-#endif
- if (m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, pText2Device, font_size, fill_color, alpha_flag, pIccTransform)) {
- return TRUE;
- }
- }
- int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(fill_color);
- if (alpha < 255) {
- return FALSE;
- }
- } else if (!(text_flags & FXTEXT_NO_NATIVETEXT)) {
-#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
- if (!(text_flags & FXFONT_CIDFONT))
-#ifdef FOXIT_CHROME_BUILD
- if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10"))
-#endif
-#endif
- if (m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, pText2Device, font_size, fill_color, alpha_flag, pIccTransform)) {
- return TRUE;
- }
- }
- CFX_AffineMatrix char2device, deviceCtm, text2Device;
- if (pText2Device) {
- char2device = *pText2Device;
- text2Device = *pText2Device;
- }
- char2device.Scale(font_size, -font_size);
- if (FXSYS_fabs(char2device.a) + FXSYS_fabs(char2device.b) > 50 * 1.0f ||
- ((m_DeviceClass == FXDC_PRINTER && !m_pDeviceDriver->IsPSPrintDriver())
- && !(text_flags & FXTEXT_PRINTIMAGETEXT))) {
- if (pFont->GetFace() != NULL || (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) {
- int nPathFlags = (text_flags & FXTEXT_NOSMOOTH) == 0 ? 0 : FXFILL_NOPATHSMOOTH;
- return DrawTextPath(nChars, pCharPos, pFont, pCache, font_size, pText2Device, NULL, NULL, fill_color, 0, NULL, nPathFlags, alpha_flag, pIccTransform);
- }
- }
- int anti_alias = FXFT_RENDER_MODE_MONO;
- FX_BOOL bNormal = FALSE;
- if ((text_flags & FXTEXT_NOSMOOTH) == 0) {
- if (m_DeviceClass == FXDC_DISPLAY && m_bpp > 1) {
- FX_BOOL bClearType;
- if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_CLEARTYPE)) {
- bClearType = FALSE;
- } else {
- bClearType = text_flags & FXTEXT_CLEARTYPE;
- }
- if ((m_RenderCaps & (FXRC_ALPHA_OUTPUT | FXRC_CMYK_OUTPUT))) {
- anti_alias = FXFT_RENDER_MODE_LCD;
- bNormal = TRUE;
- } else if (m_bpp < 16) {
- anti_alias = FXFT_RENDER_MODE_NORMAL;
- } else {
- if (bClearType == FALSE) {
- anti_alias = FXFT_RENDER_MODE_LCD;
- bNormal = TRUE;
- } else {
- anti_alias = FXFT_RENDER_MODE_LCD;
- }
- }
- }
- }
- if (pCache == NULL) {
- pCache = CFX_GEModule::Get()->GetFontCache();
- }
- CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
- FX_FONTCACHE_DEFINE(pCache, pFont);
- FXTEXT_GLYPHPOS* pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, nChars);
- if (!pGlyphAndPos) {
- return FALSE;
- }
- int iChar;
- deviceCtm = char2device;
- CFX_AffineMatrix matrixCTM = GetCTM();
- FX_FLOAT scale_x = FXSYS_fabs(matrixCTM.a);
- FX_FLOAT scale_y = FXSYS_fabs(matrixCTM.d);
- deviceCtm.Concat(scale_x, 0, 0, scale_y, 0, 0);
- text2Device.Concat(scale_x, 0, 0, scale_y, 0, 0);
- for (iChar = 0; iChar < nChars; iChar ++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
- const FXTEXT_CHARPOS& charpos = pCharPos[iChar];
- glyph.m_fOriginX = charpos.m_OriginX;
- glyph.m_fOriginY = charpos.m_OriginY;
- text2Device.Transform(glyph.m_fOriginX, glyph.m_fOriginY);
- if (anti_alias < FXFT_RENDER_MODE_LCD) {
- glyph.m_OriginX = FXSYS_round(glyph.m_fOriginX);
- } else {
- glyph.m_OriginX = (int)FXSYS_floor(glyph.m_fOriginX);
- }
- glyph.m_OriginY = FXSYS_round(glyph.m_fOriginY);
- if (charpos.m_bGlyphAdjust) {
- CFX_AffineMatrix new_matrix(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1],
- charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0);
- new_matrix.Concat(deviceCtm);
- glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont, charpos.m_GlyphIndex, charpos.m_bFontStyle, &new_matrix,
- charpos.m_FontCharWidth, anti_alias, nativetext_flags);
- } else
- glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont, charpos.m_GlyphIndex, charpos.m_bFontStyle, &deviceCtm,
- charpos.m_FontCharWidth, anti_alias, nativetext_flags);
- }
- if (anti_alias < FXFT_RENDER_MODE_LCD && nChars > 1) {
- _AdjustGlyphSpace(pGlyphAndPos, nChars);
- }
- FX_RECT bmp_rect1 = FXGE_GetGlyphsBBox(pGlyphAndPos, nChars, anti_alias);
- if (scale_x > 1 && scale_y > 1) {
- bmp_rect1.left--;
- bmp_rect1.top --;
- bmp_rect1.right ++;
- bmp_rect1.bottom ++;
- }
- FX_RECT bmp_rect(FXSYS_round((FX_FLOAT)(bmp_rect1.left) / scale_x), FXSYS_round((FX_FLOAT)(bmp_rect1.top) / scale_y),
- FXSYS_round((FX_FLOAT)bmp_rect1.right / scale_x), FXSYS_round((FX_FLOAT)bmp_rect1.bottom / scale_y));
- bmp_rect.Intersect(m_ClipBox);
- if (bmp_rect.IsEmpty()) {
- FX_Free(pGlyphAndPos);
- return TRUE;
- }
- int pixel_width = FXSYS_round(bmp_rect.Width() * scale_x);
- int pixel_height = FXSYS_round(bmp_rect.Height() * scale_y);
- int pixel_left = FXSYS_round(bmp_rect.left * scale_x);
- int pixel_top = FXSYS_round(bmp_rect.top * scale_y);
- if (anti_alias == FXFT_RENDER_MODE_MONO) {
- CFX_DIBitmap bitmap;
- if (!bitmap.Create(pixel_width, pixel_height, FXDIB_1bppMask)) {
- FX_Free(pGlyphAndPos);
- return FALSE;
- }
- bitmap.Clear(0);
- for (iChar = 0; iChar < nChars; iChar ++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
- if (glyph.m_pGlyph == NULL) {
- continue;
- }
- const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
- bitmap.TransferBitmap(glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left,
- glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top,
- pGlyph->GetWidth(), pGlyph->GetHeight(), pGlyph, 0, 0);
- }
- FX_Free(pGlyphAndPos);
- return SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color);
- }
- CFX_DIBitmap bitmap;
- if (m_bpp == 8) {
- if (!bitmap.Create(pixel_width, pixel_height, FXDIB_8bppMask)) {
- FX_Free(pGlyphAndPos);
- return FALSE;
- }
- } else {
- if (!CreateCompatibleBitmap(&bitmap, pixel_width, pixel_height)) {
- FX_Free(pGlyphAndPos);
- return FALSE;
- }
- }
- if (!bitmap.HasAlpha() && !bitmap.IsAlphaMask()) {
- bitmap.Clear(0xFFFFFFFF);
- if (!GetDIBits(&bitmap, bmp_rect.left, bmp_rect.top)) {
- FX_Free(pGlyphAndPos);
- return FALSE;
- }
- } else {
- bitmap.Clear(0);
- if (bitmap.m_pAlphaMask) {
- bitmap.m_pAlphaMask->Clear(0);
- }
- }
- int dest_width = pixel_width;
- FX_LPBYTE dest_buf = bitmap.GetBuffer();
- int dest_pitch = bitmap.GetPitch();
- int Bpp = bitmap.GetBPP() / 8;
- int a, r, g, b;
- if (anti_alias == FXFT_RENDER_MODE_LCD) {
- _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
- ArgbDecode(fill_color, a, r, g, b);
- r = FX_GAMMA(r);
- g = FX_GAMMA(g);
- b = FX_GAMMA(b);
- }
- for (iChar = 0; iChar < nChars; iChar ++) {
- FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
- if (glyph.m_pGlyph == NULL) {
- continue;
- }
- const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
- int left = glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left;
- int top = glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top;
- int ncols = pGlyph->GetWidth();
- int nrows = pGlyph->GetHeight();
- if (anti_alias == FXFT_RENDER_MODE_NORMAL) {
- if (!bitmap.CompositeMask(left, top, ncols, nrows, pGlyph, fill_color,
- 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) {
- FX_Free(pGlyphAndPos);
- return FALSE;
- }
- continue;
- }
- FX_BOOL bBGRStripe = text_flags & FXTEXT_BGR_STRIPE;
- ncols /= 3;
- int x_subpixel = (int)(glyph.m_fOriginX * 3) % 3;
- FX_LPBYTE src_buf = pGlyph->GetBuffer();
- int src_pitch = pGlyph->GetPitch();
- int start_col = left;
- if (start_col < 0) {
- start_col = 0;
- }
- int end_col = left + ncols;
- if (end_col > dest_width) {
- end_col = dest_width;
- }
- if (start_col >= end_col) {
- continue;
- }
- if (bitmap.GetFormat() == FXDIB_Argb) {
- for (int row = 0; row < nrows; row ++) {
- int dest_row = row + top;
- if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
- continue;
- }
- FX_LPBYTE src_scan = src_buf + row * src_pitch + (start_col - left) * 3;
- FX_LPBYTE dest_scan = dest_buf + dest_row * dest_pitch + (start_col << 2);
- if (bBGRStripe) {
- if (x_subpixel == 0) {
- for (int col = start_col; col < end_col; col ++) {
- int src_alpha = src_scan[2];
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[1];
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[0];
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- } else if (x_subpixel == 1) {
- int src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- if (start_col > left) {
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- }
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- for (int col = start_col + 1; col < end_col - 1; col ++) {
- int src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- } else {
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- if (start_col > left) {
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- }
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- for (int col = start_col + 1; col < end_col - 1; col ++) {
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- }
- } else {
- if (x_subpixel == 0) {
- for (int col = start_col; col < end_col; col ++) {
- if (bNormal) {
- int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[2]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- } else if (x_subpixel == 1) {
- if (bNormal) {
- int src_alpha1 = start_col > left ? ((src_scan[-1] + src_scan[0] + src_scan[1]) / 3) : ((src_scan[0] + src_scan[1]) / 3);
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- } else {
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- } else {
- FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- }
- dest_scan += 4;
- src_scan += 3;
- }
- } else {
- if (start_col > left) {
- int src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- for (int col = start_col + 1; col < end_col; col ++) {
- if (bNormal) {
- int src_alpha1 = (src_scan[-1] + src_scan[0] + src_scan[1]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- } else {
- if (bNormal) {
- int src_alpha1 = start_col > left ? ((src_scan[-2] + src_scan[-1] + src_scan[0]) / 3) : ((src_scan[0]) / 3);
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- } else {
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- } else {
- FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- }
- dest_scan += 4;
- src_scan += 3;
- }
- } else {
- if (start_col > left) {
- int src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- for (int col = start_col + 1; col < end_col; col ++) {
- if (bNormal) {
- int src_alpha1 = (src_scan[-2] + src_scan[-1] + src_scan[0]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- FX_BYTE back_alpha = dest_scan[3];
- if (back_alpha == 0) {
- FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- if (src_alpha1 == 0) {
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
- dest_scan[3] = dest_alpha;
- int alpha_ratio = src_alpha1 * 255 / dest_alpha;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
- dest_scan += 4;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan[3] = 255;
- dest_scan += 4;
- src_scan += 3;
- }
- }
- }
- }
- } else {
- for (int row = 0; row < nrows; row ++) {
- int dest_row = row + top;
- if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
- continue;
- }
- FX_LPBYTE src_scan = src_buf + row * src_pitch + (start_col - left) * 3;
- FX_LPBYTE dest_scan = dest_buf + dest_row * dest_pitch + start_col * Bpp;
- if (bBGRStripe) {
- if (x_subpixel == 0) {
- for (int col = start_col; col < end_col; col ++) {
- int src_alpha = src_scan[2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- } else if (x_subpixel == 1) {
- int src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- if (start_col > left) {
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- }
- dest_scan += Bpp;
- src_scan += 3;
- for (int col = start_col + 1; col < end_col - 1; col ++) {
- int src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- } else {
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- if (start_col > left) {
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- }
- dest_scan += Bpp;
- src_scan += 3;
- for (int col = start_col + 1; col < end_col - 1; col ++) {
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- }
- } else {
- if (x_subpixel == 0) {
- for (int col = start_col; col < end_col; col ++) {
- if (bNormal) {
- int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[2]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[2];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- } else if (x_subpixel == 1) {
- if (bNormal) {
- int src_alpha1 = start_col > left ? (src_scan[0] + src_scan[1] + src_scan[-1]) / 3 : (src_scan[0] + src_scan[1]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- } else {
- if (start_col > left) {
- int src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- for (int col = start_col + 1; col < end_col; col ++) {
- if (bNormal) {
- int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[-1]) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[1];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- } else {
- if (bNormal) {
- int src_alpha1 = start_col > left ? (src_scan[0] + src_scan[-2] + src_scan[-1]) / 3 : src_scan[0] / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- } else {
- if (start_col > left) {
- int src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- }
- int src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- for (int col = start_col + 1; col < end_col; col ++) {
- if (bNormal) {
- int src_alpha1 = ((int)(src_scan[0]) + (int)(src_scan[-2]) + (int)(src_scan[-1])) / 3;
- ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
- src_alpha1 = src_alpha1 * a / 255;
- if (src_alpha1 == 0) {
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
- dest_scan += Bpp;
- src_scan += 3;
- continue;
- }
- int src_alpha = src_scan[-2];
- ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
- src_alpha = src_scan[-1];
- ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
- src_alpha = src_scan[0];
- ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
- src_alpha = src_alpha * a / 255;
- dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
- dest_scan += Bpp;
- src_scan += 3;
- }
- }
- }
- }
- }
- }
- if (bitmap.IsAlphaMask()) {
- SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color, alpha_flag, pIccTransform);
- } else {
- SetDIBits(&bitmap, bmp_rect.left, bmp_rect.top);
- }
- FX_Free(pGlyphAndPos);
- return TRUE;
-}
-FX_BOOL CFX_RenderDevice::DrawTextPath(int nChars, const FXTEXT_CHARPOS* pCharPos,
- CFX_Font* pFont, CFX_FontCache* pCache,
- FX_FLOAT font_size, const CFX_AffineMatrix* pText2User,
- const CFX_AffineMatrix* pUser2Device, const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color, FX_ARGB stroke_color, CFX_PathData* pClippingPath, int nFlag,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (pCache == NULL) {
- pCache = CFX_GEModule::Get()->GetFontCache();
- }
- CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
- FX_FONTCACHE_DEFINE(pCache, pFont);
- for (int iChar = 0; iChar < nChars; iChar ++) {
- const FXTEXT_CHARPOS& charpos = pCharPos[iChar];
- CFX_AffineMatrix matrix;
- if (charpos.m_bGlyphAdjust)
- matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1],
- charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0);
- matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, charpos.m_OriginY);
- const CFX_PathData* pPath = pFaceCache->LoadGlyphPath(pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth);
- if (pPath == NULL) {
- continue;
- }
- matrix.Concat(*pText2User);
- CFX_PathData TransformedPath(*pPath);
- TransformedPath.Transform(&matrix);
- FX_BOOL bHasAlpha = FXGETFLAG_COLORTYPE(alpha_flag) ?
- (FXGETFLAG_ALPHA_FILL(alpha_flag) || FXGETFLAG_ALPHA_STROKE(alpha_flag)) :
- (fill_color || stroke_color);
- if (bHasAlpha) {
- int fill_mode = nFlag;
- if (FXGETFLAG_COLORTYPE(alpha_flag)) {
- if (FXGETFLAG_ALPHA_FILL(alpha_flag)) {
- fill_mode |= FXFILL_WINDING;
- }
- } else {
- if (fill_color) {
- fill_mode |= FXFILL_WINDING;
- }
- }
- fill_mode |= FX_FILL_TEXT_MODE;
- if (!DrawPath(&TransformedPath, pUser2Device, pGraphState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type)) {
- return FALSE;
- }
- }
- if (pClippingPath) {
- pClippingPath->Append(&TransformedPath, pUser2Device);
- }
- }
- return TRUE;
-}
-CFX_FontCache::~CFX_FontCache()
-{
- FreeCache(TRUE);
-}
-CFX_FaceCache* CFX_FontCache::GetCachedFace(CFX_Font* pFont)
-{
- FX_BOOL bExternal = pFont->GetFace() == NULL;
- void* face = bExternal ? pFont->GetSubstFont()->m_ExtHandle : pFont->GetFace();
- CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap;
- CFX_CountedFaceCache* counted_face_cache = NULL;
- if (map.Lookup((FXFT_Face)face, counted_face_cache)) {
- counted_face_cache->m_nCount++;
- return counted_face_cache->m_Obj;
- }
- CFX_FaceCache* face_cache = NULL;
- face_cache = FX_NEW CFX_FaceCache(bExternal ? NULL : (FXFT_Face)face);
- if (face_cache == NULL) {
- return NULL;
- }
- counted_face_cache = FX_NEW CFX_CountedFaceCache;
- if (!counted_face_cache) {
- if (face_cache) {
- delete face_cache;
- face_cache = NULL;
- }
- return NULL;
- }
- counted_face_cache->m_nCount = 2;
- counted_face_cache->m_Obj = face_cache;
- map.SetAt((FXFT_Face)face, counted_face_cache);
- return face_cache;
-}
-void CFX_FontCache::ReleaseCachedFace(CFX_Font* pFont)
-{
- FX_BOOL bExternal = pFont->GetFace() == NULL;
- void* face = bExternal ? pFont->GetSubstFont()->m_ExtHandle : pFont->GetFace();
- CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap;
- CFX_CountedFaceCache* counted_face_cache = NULL;
- if (!map.Lookup((FXFT_Face)face, counted_face_cache)) {
- return;
- }
- if (counted_face_cache->m_nCount > 1) {
- counted_face_cache->m_nCount--;
- }
-}
-void CFX_FontCache::FreeCache(FX_BOOL bRelease)
-{
- {
- FX_POSITION pos;
- pos = m_FTFaceMap.GetStartPosition();
- while (pos) {
- FXFT_Face face;
- CFX_CountedFaceCache* cache;
- m_FTFaceMap.GetNextAssoc(pos, face, cache);
- if (bRelease || cache->m_nCount < 2) {
- delete cache->m_Obj;
- delete cache;
- m_FTFaceMap.RemoveKey(face);
- }
- }
- pos = m_ExtFaceMap.GetStartPosition();
- while (pos) {
- FXFT_Face face;
- CFX_CountedFaceCache* cache;
- m_ExtFaceMap.GetNextAssoc(pos, face, cache);
- if (bRelease || cache->m_nCount < 2) {
- delete cache->m_Obj;
- delete cache;
- m_ExtFaceMap.RemoveKey(face);
- }
- }
- }
-}
-CFX_FaceCache::CFX_FaceCache(FXFT_Face face)
-{
- m_Face = face;
- m_pBitmap = NULL;
-}
-CFX_FaceCache::~CFX_FaceCache()
-{
- FX_POSITION pos = m_SizeMap.GetStartPosition();
- CFX_ByteString Key;
- CFX_SizeGlyphCache* pSizeCache = NULL;
- while(pos) {
- m_SizeMap.GetNextAssoc( pos, Key, (void*&)pSizeCache);
- delete pSizeCache;
- }
- m_SizeMap.RemoveAll();
- pos = m_PathMap.GetStartPosition();
- FX_LPVOID key1;
- CFX_PathData* pPath;
- while (pos) {
- m_PathMap.GetNextAssoc(pos, key1, (FX_LPVOID&)pPath);
- delete pPath;
- }
- if (m_pBitmap) {
- delete m_pBitmap;
- }
- m_PathMap.RemoveAll();
-}
-#if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_)|| defined(_FPDFAPI_MINI_))
-void CFX_FaceCache::InitPlatform()
-{
-}
-#endif
-CFX_GlyphBitmap* CFX_FaceCache::LookUpGlyphBitmap(CFX_Font* pFont, const CFX_AffineMatrix* pMatrix,
- CFX_ByteStringC& FaceGlyphsKey, FX_DWORD glyph_index, FX_BOOL bFontStyle,
- int dest_width, int anti_alias)
-{
- CFX_SizeGlyphCache* pSizeCache = NULL;
- if (!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
- pSizeCache = FX_NEW CFX_SizeGlyphCache;
- if (pSizeCache == NULL) {
- return NULL;
- }
- m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
- }
- CFX_GlyphBitmap* pGlyphBitmap = NULL;
- if (pSizeCache->m_GlyphMap.Lookup((FX_LPVOID)(FX_UINTPTR)glyph_index, (void*&)pGlyphBitmap)) {
- return pGlyphBitmap;
- }
- pGlyphBitmap = RenderGlyph(pFont, glyph_index, bFontStyle, pMatrix, dest_width, anti_alias);
- if (pGlyphBitmap == NULL) {
- return NULL;
- }
- pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)glyph_index, pGlyphBitmap);
- return pGlyphBitmap;
-}
-const CFX_GlyphBitmap* CFX_FaceCache::LoadGlyphBitmap(CFX_Font* pFont, FX_DWORD glyph_index, FX_BOOL bFontStyle, const CFX_AffineMatrix* pMatrix,
- int dest_width, int anti_alias, int& text_flags)
-{
- if (glyph_index == (FX_DWORD) - 1) {
- return NULL;
- }
- _CFX_UniqueKeyGen keygen;
-#if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_)|| defined(_FPDFAPI_MINI_))
- if (pFont->GetSubstFont())
- keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
- (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias,
- pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
- else
- keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
- (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias);
-#else
- if (text_flags & FXTEXT_NO_NATIVETEXT) {
- if (pFont->GetSubstFont())
- keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
- (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias,
- pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
- else
- keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
- (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias);
- } else {
- if (pFont->GetSubstFont())
- keygen.Generate(10, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
- (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias,
- pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical(), 3);
- else
- keygen.Generate(7, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
- (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias, 3);
- }
-#endif
- CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
-#if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_)|| defined(_FPDFAPI_MINI_))
- return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFontStyle, dest_width, anti_alias);
-#else
- if (text_flags & FXTEXT_NO_NATIVETEXT) {
- return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFontStyle, dest_width, anti_alias);
- } else {
- CFX_GlyphBitmap* pGlyphBitmap;
- CFX_SizeGlyphCache* pSizeCache = NULL;
- if (m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
- if (pSizeCache->m_GlyphMap.Lookup((FX_LPVOID)(FX_UINTPTR)glyph_index, (void*&)pGlyphBitmap)) {
- return pGlyphBitmap;
- }
- pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, dest_width, anti_alias);
- if (pGlyphBitmap) {
- pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)glyph_index, pGlyphBitmap);
- return pGlyphBitmap;
- }
- } else {
- pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, dest_width, anti_alias);
- if (pGlyphBitmap) {
- pSizeCache = FX_NEW CFX_SizeGlyphCache;
- if (pSizeCache == NULL) {
- return NULL;
- }
- m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
- pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)glyph_index, pGlyphBitmap);
- return pGlyphBitmap;
- }
- }
- if (pFont->GetSubstFont())
- keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
- (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias,
- pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
- else
- keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
- (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias);
- CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
- text_flags |= FXTEXT_NO_NATIVETEXT;
- return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFontStyle, dest_width, anti_alias);
- }
-#endif
-}
-CFX_SizeGlyphCache::~CFX_SizeGlyphCache()
-{
- FX_POSITION pos = m_GlyphMap.GetStartPosition();
- FX_LPVOID Key;
- CFX_GlyphBitmap* pGlyphBitmap = NULL;
- while(pos) {
- m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap);
- delete pGlyphBitmap;
- }
- m_GlyphMap.RemoveAll();
-}
-#if defined(_FPDFAPI_MINI_)
-#define CONTRAST_RAMP_STEP 16
-#else
-#define CONTRAST_RAMP_STEP 1
-#endif
-static const FX_BYTE g_adjust_contrast11[256] = {
- 0, 0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 21, 22, 24, 25, 26, 28, 29, 31,
- 32, 33, 35, 36, 38, 39, 40, 42, 43, 45, 46, 48, 49, 51, 52, 54, 55, 56, 58, 59, 61, 62, 64, 65,
- 67, 68, 70, 71, 72, 74, 75, 77, 78, 80, 81, 83, 84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 99, 100,
- 101, 103, 104, 106, 107, 109, 110, 111, 113, 114, 116, 117, 118, 120, 121, 123, 124, 125, 127,
- 128, 130, 131, 132, 134, 135, 136, 138, 139, 140, 142, 143, 144, 146, 147, 148, 149, 151, 152,
- 153, 155, 156, 157, 158, 160, 161, 162, 163, 165, 166, 167, 168, 169, 171, 172, 173, 174, 175,
- 177, 178, 179, 180, 181, 182, 183, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
- 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
- 215, 216, 217, 218, 219, 220, 221, 221, 222, 223, 224, 224, 225, 226, 227, 227, 228, 229, 230,
- 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 237, 238, 239, 239, 240, 240, 241, 241,
- 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
- 250, 250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 254, 254,
- 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255,
-};
-static const FX_BYTE g_adjust_contrast15[256] = {
- 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
- 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 40, 41, 42, 43, 45, 46, 47, 48, 50, 51,
- 52, 54, 55, 56, 58, 59, 60, 62, 63, 64, 66, 67, 68, 70, 71, 73, 74, 75, 77, 78, 80, 81, 82, 84, 85, 87,
- 88, 90, 91, 93, 94, 95, 97, 98, 100, 101, 103, 104, 106, 107, 109, 110, 111, 113, 114, 116, 117, 119,
- 120, 122, 123, 125, 126, 128, 129, 130, 132, 133, 135, 136, 138, 139, 141, 142, 143, 145, 146, 148,
- 149, 150, 152, 153, 155, 156, 157, 159, 160, 161, 163, 164, 166, 167, 168, 170, 171, 172, 174, 175,
- 176, 177, 179, 180, 181, 183, 184, 185, 186, 188, 189, 190, 191, 192, 194, 195, 196, 197, 198, 199,
- 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
- 221, 222, 223, 224, 225, 226, 227, 227, 228, 229, 230, 231, 232, 232, 233, 234, 235, 235, 236, 237,
- 237, 238, 239, 239, 240, 241, 241, 242, 242, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248,
- 248, 249, 249, 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 253, 254, 254,
- 254, 254, 254, 254, 254, 254, 254, 254, 254, 255,
-};
-static void _CalcContrastRamp(FX_LPBYTE ramp, int level)
-{
- int contrast_min = 0, contrast_max = 255 - level, i;
- for (i = 0; i < contrast_min; i ++) {
- ramp[i] = 0;
- }
- for (i = contrast_min; i < contrast_max; i ++) {
- ramp[i] = 255 * (i - contrast_min) / (contrast_max - contrast_min);
- }
- for (i = contrast_max; i < 256; i ++) {
- ramp[i] = 255;
- }
-}
-void CFX_Font::AdjustMMParams(int glyph_index, int dest_width, int weight)
-{
- FXFT_MM_Var pMasters = NULL;
- FXFT_Get_MM_Var(m_Face, &pMasters);
- if (pMasters == NULL) {
- return;
- }
- long coords[2];
- if (weight == 0) {
- coords[0] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 0)) / 65536;
- } else {
- coords[0] = weight;
- }
- if (dest_width == 0) {
- coords[1] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
- } else {
- int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
- int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
- coords[1] = min_param;
- int error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
- error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / FXFT_Get_Face_UnitsPerEM(m_Face);
- coords[1] = max_param;
- error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
- error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / FXFT_Get_Face_UnitsPerEM(m_Face);
- if (max_width == min_width) {
- return;
- }
- int param = min_param + (max_param - min_param) * (dest_width - min_width) / (max_width - min_width);
- coords[1] = param;
- }
- FXFT_Free(m_Face, pMasters);
- FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
-}
-extern const char g_AngleSkew[30] = {
- 0, 2, 3, 5, 7, 9, 11, 12, 14, 16,
- 18, 19, 21, 23, 25, 27, 29, 31, 32, 34,
- 36, 38, 40, 42, 45, 47, 49, 51, 53, 55,
-};
-static const FX_BYTE g_WeightPow[100] = {
- 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36,
- 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42,
- 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47,
- 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51,
- 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53,
-};
-extern const FX_BYTE g_WeightPow_11[100] = {
- 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22,
- 23, 24, 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40,
- 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46,
- 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52, 52,
- 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56,
- 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58,
-};
-extern const FX_BYTE g_WeightPow_SHIFTJIS[100] = {
- 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21, 22, 24, 26, 28,
- 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48, 49, 49, 49, 50, 50, 50, 50,
- 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55,
- 55, 55, 55, 56, 56, 56, 56, 56 , 56, 57, 57, 57 , 57 , 57, 57, 57, 58, 58, 58, 58, 58,
- 58, 58, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60,
-};
-static void _GammaAdjust(FX_LPBYTE pData, int nWid, int nHei, int src_pitch, FX_LPCBYTE gammaTable)
-{
- int count = nHei * src_pitch;
- for(int i = 0; i < count; i++) {
- pData[i] = gammaTable[pData[i]];
- }
-}
-static void _ContrastAdjust(FX_LPBYTE pDataIn, FX_LPBYTE pDataOut, int nWid, int nHei, int nSrcRowBytes, int nDstRowBytes)
-{
- int col, row, temp;
- int max = 0, min = 255;
- FX_FLOAT rate;
- for (row = 0; row < nHei; row ++) {
- FX_LPBYTE pRow = pDataIn + row * nSrcRowBytes;
- for (col = 0; col < nWid; col++) {
- temp = *pRow ++;
- if (temp > max) {
- max = temp;
- }
- if (temp < min) {
- min = temp;
- }
- }
- }
- temp = max - min;
- if (0 == temp || 255 == temp) {
- int rowbytes = FXSYS_abs(nSrcRowBytes) > nDstRowBytes ? nDstRowBytes : FXSYS_abs(nSrcRowBytes);
- for (row = 0; row < nHei; row ++) {
- FXSYS_memcpy32(pDataOut + row * nDstRowBytes, pDataIn + row * nSrcRowBytes, rowbytes);
- }
- return;
- }
- rate = 255.f / temp;
- for (row = 0; row < nHei; row ++) {
- FX_LPBYTE pSrcRow = pDataIn + row * nSrcRowBytes;
- FX_LPBYTE pDstRow = pDataOut + row * nDstRowBytes;
- for (col = 0; col < nWid; col ++) {
- temp = (int)((*(pSrcRow++) - min) * rate + 0.5);
- if (temp > 255) {
- temp = 255;
- } else if (temp < 0) {
- temp = 0;
- }
- *pDstRow ++ = (FX_BYTE)temp;
- }
- }
-}
-CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(CFX_Font* pFont, FX_DWORD glyph_index, FX_BOOL bFontStyle,
- const CFX_AffineMatrix* pMatrix, int dest_width, int anti_alias)
-{
- if (m_Face == NULL) {
- return NULL;
- }
- FXFT_Matrix ft_matrix;
- ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536);
- ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536);
- ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536);
- ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536);
- FX_BOOL bUseCJKSubFont = FALSE;
- const CFX_SubstFont* pSubstFont = pFont->GetSubstFont();
- if (pSubstFont) {
- bUseCJKSubFont = pSubstFont->m_bSubstOfCJK && bFontStyle;
- int skew = 0;
- if (bUseCJKSubFont) {
- skew = pSubstFont->m_bItlicCJK ? -15 : 0;
- } else {
- skew = pSubstFont->m_ItalicAngle;
- }
- if (skew) {
- skew = skew <= -30 ? -58 : -g_AngleSkew[-skew];
- if (pFont->IsVertical()) {
- ft_matrix.yx += ft_matrix.yy * skew / 100;
- } else {
- ft_matrix.xy += -ft_matrix.xx * skew / 100;
- }
- }
- if (pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
- pFont->AdjustMMParams(glyph_index, dest_width, pFont->GetSubstFont()->m_Weight);
- }
- }
- int transflag = FXFT_Get_Face_Internal_Flag(m_Face);
- FXFT_Set_Transform(m_Face, &ft_matrix, 0);
- int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT) ? FXFT_LOAD_NO_BITMAP : (FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
- int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
- if (error) {
- FXFT_Set_Face_Internal_Flag(m_Face, transflag);
- return NULL;
- }
- int weight = 0;
- if (bUseCJKSubFont) {
- weight = pSubstFont->m_WeightCJK;
- } else {
- weight = pSubstFont ? pSubstFont->m_Weight : 0;
- }
- if (pSubstFont && !(pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && weight > 400) {
- int index = (weight - 400) / 10;
- if (index >= 100) {
- FXFT_Set_Face_Internal_Flag(m_Face, transflag);
- return NULL;
- }
- int level = 0;
- if (pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) {
- level = g_WeightPow_SHIFTJIS[index] * 2 * (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) / 36655;
- } else {
- level = g_WeightPow_11[index] * (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) / 36655;
- }
- FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
- }
- FXFT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary, FT_LCD_FILTER_DEFAULT);
- error = FXFT_Render_Glyph(m_Face, anti_alias);
- if (error) {
- FXFT_Set_Face_Internal_Flag(m_Face, transflag);
- return NULL;
- }
- int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(m_Face));
- int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(m_Face));
- if (bmwidth > 2048 || bmheight > 2048) {
- FXFT_Set_Face_Internal_Flag(m_Face, transflag);
- return NULL;
- }
- int dib_width = bmwidth;
- CFX_GlyphBitmap* pGlyphBitmap = FX_NEW CFX_GlyphBitmap;
- if (!pGlyphBitmap) {
- return NULL;
- }
- pGlyphBitmap->m_Bitmap.Create(dib_width, bmheight,
- anti_alias == FXFT_RENDER_MODE_MONO ? FXDIB_1bppMask : FXDIB_8bppMask);
- pGlyphBitmap->m_Left = FXFT_Get_Glyph_BitmapLeft(m_Face);
- pGlyphBitmap->m_Top = FXFT_Get_Glyph_BitmapTop(m_Face);
- int dest_pitch = pGlyphBitmap->m_Bitmap.GetPitch();
- int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(m_Face));
- FX_BYTE* pDestBuf = pGlyphBitmap->m_Bitmap.GetBuffer();
- FX_BYTE* pSrcBuf = (FX_BYTE*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(m_Face));
- if (anti_alias != FXFT_RENDER_MODE_MONO && FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) == FXFT_PIXEL_MODE_MONO) {
- int bytes = anti_alias == FXFT_RENDER_MODE_LCD ? 3 : 1;
- for(int i = 0; i < bmheight; i++)
- for(int n = 0; n < bmwidth; n++) {
- FX_BYTE data = (pSrcBuf[i * src_pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0;
- for (int b = 0; b < bytes; b ++) {
- pDestBuf[i * dest_pitch + n * bytes + b] = data;
- }
- }
- } else {
- FXSYS_memset32(pDestBuf, 0, dest_pitch * bmheight);
- if (anti_alias == FXFT_RENDER_MODE_MONO && FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) == FXFT_PIXEL_MODE_MONO) {
- int rowbytes = FXSYS_abs(src_pitch) > dest_pitch ? dest_pitch : FXSYS_abs(src_pitch);
- for (int row = 0; row < bmheight; row ++) {
- FXSYS_memcpy32(pDestBuf + row * dest_pitch, pSrcBuf + row * src_pitch, rowbytes);
- }
- } else {
- _ContrastAdjust(pSrcBuf, pDestBuf, bmwidth, bmheight, src_pitch, dest_pitch);
- _GammaAdjust(pDestBuf, bmwidth, bmheight, dest_pitch, CFX_GEModule::Get()->GetTextGammaTable());
- }
- }
- FXFT_Set_Face_Internal_Flag(m_Face, transflag);
- return pGlyphBitmap;
-}
-FX_BOOL _OutputGlyph(void* dib, int x, int y, CFX_Font* pFont,
- int glyph_index, FX_ARGB argb)
-{
- CFX_DIBitmap* pDib = (CFX_DIBitmap*)dib;
- FXFT_Face face = pFont->GetFace();
- int error = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_BITMAP);
- if (error) {
- return FALSE;
- }
- error = FXFT_Render_Glyph(face, FXFT_RENDER_MODE_NORMAL);
- if (error) {
- return FALSE;
- }
- int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(face));
- int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(face));
- int left = FXFT_Get_Glyph_BitmapLeft(face);
- int top = FXFT_Get_Glyph_BitmapTop(face);
- FX_LPCBYTE src_buf = (FX_LPCBYTE)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(face));
- int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(face));
- CFX_DIBitmap mask;
- mask.Create(bmwidth, bmheight, FXDIB_8bppMask);
- FX_LPBYTE dest_buf = mask.GetBuffer();
- int dest_pitch = mask.GetPitch();
- for (int row = 0; row < bmheight; row ++) {
- FX_LPCBYTE src_scan = src_buf + row * src_pitch;
- FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
- FXSYS_memcpy32(dest_scan, src_scan, dest_pitch);
- }
- pDib->CompositeMask(x + left, y - top, bmwidth, bmheight, &mask, argb, 0, 0);
- return TRUE;
-}
-FX_BOOL OutputText(void* dib, int x, int y, CFX_Font* pFont, double font_size,
- CFX_AffineMatrix* pText_matrix, unsigned short const* text, unsigned long argb)
-{
- if (!pFont) {
- return FALSE;
- }
- FXFT_Face face = pFont->GetFace();
- FXFT_Select_Charmap(pFont->m_Face, FXFT_ENCODING_UNICODE);
- int transflag = FXFT_Get_Face_Internal_Flag(pFont->m_Face);
- if (pText_matrix) {
- FXFT_Matrix ft_matrix;
- ft_matrix.xx = (signed long)(pText_matrix->a / 64 * 65536);
- ft_matrix.xy = (signed long)(pText_matrix->c / 64 * 65536);
- ft_matrix.yx = (signed long)(pText_matrix->b / 64 * 65536);
- ft_matrix.yy = (signed long)(pText_matrix->d / 64 * 65536);
- FXFT_Set_Transform(face, &ft_matrix, 0);
- }
- FX_FLOAT x_pos = 0;
- for (; *text != 0; text ++) {
- FX_WCHAR unicode = *text;
- int glyph_index = FXFT_Get_Char_Index(pFont->m_Face, unicode);
- if (glyph_index <= 0) {
- continue;
- }
- int err = FXFT_Load_Glyph(pFont->m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
- if (err) {
- continue;
- }
- int w = FXFT_Get_Glyph_HoriAdvance(pFont->m_Face);
- int em = FXFT_Get_Face_UnitsPerEM(pFont->m_Face);
- FX_FLOAT x1, y1;
- pText_matrix->Transform(x_pos, 0, x1, y1);
- _OutputGlyph(dib, (int)x1 + x, (int) - y1 + y, pFont,
- glyph_index, argb);
- x_pos += (FX_FLOAT)w / em;
- }
- FXFT_Set_Face_Internal_Flag(pFont->m_Face, transflag);
- return TRUE;
-}
-FX_BOOL OutputGlyph(void* dib, int x, int y, CFX_Font* pFont, double font_size,
- CFX_AffineMatrix* pMatrix, unsigned long glyph_index, unsigned long argb)
-{
- FXFT_Matrix ft_matrix;
- if (pMatrix) {
- ft_matrix.xx = (signed long)(pMatrix->a * font_size / 64 * 65536);
- ft_matrix.xy = (signed long)(pMatrix->c * font_size / 64 * 65536);
- ft_matrix.yx = (signed long)(pMatrix->b * font_size / 64 * 65536);
- ft_matrix.yy = (signed long)(pMatrix->d * font_size / 64 * 65536);
- } else {
- ft_matrix.xx = (signed long)(font_size / 64 * 65536);
- ft_matrix.xy = ft_matrix.yx = 0;
- ft_matrix.yy = (signed long)(font_size / 64 * 65536);
- }
- int transflag = FXFT_Get_Face_Internal_Flag(pFont->m_Face);
- FXFT_Set_Transform(pFont->m_Face, &ft_matrix, 0);
- FX_BOOL ret = _OutputGlyph(dib, x, y, pFont,
- glyph_index, argb);
- FXFT_Set_Face_Internal_Flag(pFont->m_Face, transflag);
- return ret;
-}
-const CFX_PathData* CFX_FaceCache::LoadGlyphPath(CFX_Font* pFont, FX_DWORD glyph_index, int dest_width)
-{
- if (m_Face == NULL || glyph_index == (FX_DWORD) - 1) {
- return NULL;
- }
- CFX_PathData* pGlyphPath = NULL;
- FX_LPVOID key;
- if (pFont->GetSubstFont())
- key = (FX_LPVOID)(FX_UINTPTR)(glyph_index + ((pFont->GetSubstFont()->m_Weight / 16) << 15) +
- ((pFont->GetSubstFont()->m_ItalicAngle / 2) << 21) + ((dest_width / 16) << 25) +
- (pFont->IsVertical() << 31));
- else {
- key = (FX_LPVOID)(FX_UINTPTR)glyph_index;
- }
- if (m_PathMap.Lookup(key, (FX_LPVOID&)pGlyphPath)) {
- return pGlyphPath;
- }
- pGlyphPath = pFont->LoadGlyphPath(glyph_index, dest_width);
- m_PathMap.SetAt(key, pGlyphPath);
- return pGlyphPath;
-}
-typedef struct {
- FX_BOOL m_bCount;
- int m_PointCount;
- FX_PATHPOINT* m_pPoints;
- int m_CurX;
- int m_CurY;
- FX_FLOAT m_CoordUnit;
-} OUTLINE_PARAMS;
-void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param)
-{
- if (param->m_PointCount >= 2 && param->m_pPoints[param->m_PointCount - 2].m_Flag == FXPT_MOVETO &&
- param->m_pPoints[param->m_PointCount - 2].m_PointX == param->m_pPoints[param->m_PointCount - 1].m_PointX &&
- param->m_pPoints[param->m_PointCount - 2].m_PointY == param->m_pPoints[param->m_PointCount - 1].m_PointY) {
- param->m_PointCount -= 2;
- }
- if (param->m_PointCount >= 4 && param->m_pPoints[param->m_PointCount - 4].m_Flag == FXPT_MOVETO &&
- param->m_pPoints[param->m_PointCount - 3].m_Flag == FXPT_BEZIERTO &&
- param->m_pPoints[param->m_PointCount - 3].m_PointX == param->m_pPoints[param->m_PointCount - 4].m_PointX &&
- param->m_pPoints[param->m_PointCount - 3].m_PointY == param->m_pPoints[param->m_PointCount - 4].m_PointY &&
- param->m_pPoints[param->m_PointCount - 2].m_PointX == param->m_pPoints[param->m_PointCount - 4].m_PointX &&
- param->m_pPoints[param->m_PointCount - 2].m_PointY == param->m_pPoints[param->m_PointCount - 4].m_PointY &&
- param->m_pPoints[param->m_PointCount - 1].m_PointX == param->m_pPoints[param->m_PointCount - 4].m_PointX &&
- param->m_pPoints[param->m_PointCount - 1].m_PointY == param->m_pPoints[param->m_PointCount - 4].m_PointY) {
- param->m_PointCount -= 4;
- }
-}
-extern "C" {
- static int _Outline_MoveTo(const FXFT_Vector* to, void* user)
- {
- OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
- if (!param->m_bCount) {
- _Outline_CheckEmptyContour(param);
- param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount].m_Flag = FXPT_MOVETO;
- param->m_CurX = to->x;
- param->m_CurY = to->y;
- if (param->m_PointCount) {
- param->m_pPoints[param->m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
- }
- }
- param->m_PointCount ++;
- return 0;
- }
-};
-extern "C" {
- static int _Outline_LineTo(const FXFT_Vector* to, void* user)
- {
- OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
- if (!param->m_bCount) {
- param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount].m_Flag = FXPT_LINETO;
- param->m_CurX = to->x;
- param->m_CurY = to->y;
- }
- param->m_PointCount ++;
- return 0;
- }
-};
-extern "C" {
- static int _Outline_ConicTo(const FXFT_Vector* control, const FXFT_Vector* to, void* user)
- {
- OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
- if (!param->m_bCount) {
- param->m_pPoints[param->m_PointCount].m_PointX = (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount].m_PointY = (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO;
- param->m_pPoints[param->m_PointCount + 1].m_PointX = (control->x + (to->x - control->x) / 3) / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount + 1].m_PointY = (control->y + (to->y - control->y) / 3) / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO;
- param->m_pPoints[param->m_PointCount + 2].m_PointX = to->x / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount + 2].m_PointY = to->y / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO;
- param->m_CurX = to->x;
- param->m_CurY = to->y;
- }
- param->m_PointCount += 3;
- return 0;
- }
-};
-extern "C" {
- static int _Outline_CubicTo(const FXFT_Vector* control1, const FXFT_Vector* control2, const FXFT_Vector* to, void* user)
- {
- OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
- if (!param->m_bCount) {
- param->m_pPoints[param->m_PointCount].m_PointX = control1->x / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount].m_PointY = control1->y / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO;
- param->m_pPoints[param->m_PointCount + 1].m_PointX = control2->x / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount + 1].m_PointY = control2->y / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO;
- param->m_pPoints[param->m_PointCount + 2].m_PointX = to->x / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount + 2].m_PointY = to->y / param->m_CoordUnit;
- param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO;
- param->m_CurX = to->x;
- param->m_CurY = to->y;
- }
- param->m_PointCount += 3;
- return 0;
- }
-};
-CFX_PathData* CFX_Font::LoadGlyphPath(FX_DWORD glyph_index, int dest_width)
-{
- if (m_Face == NULL) {
- return NULL;
- }
- FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
- FXFT_Matrix ft_matrix = {65536, 0, 0, 65536};
- if (m_pSubstFont) {
- if (m_pSubstFont->m_ItalicAngle) {
- int skew = m_pSubstFont->m_ItalicAngle;
- skew = skew <= -30 ? -58 : -g_AngleSkew[-skew];
- if (m_bVertical) {
- ft_matrix.yx += ft_matrix.yy * skew / 100;
- } else {
- ft_matrix.xy += -ft_matrix.xx * skew / 100;
- }
- }
- if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
- AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight);
- }
- }
- int transflag = FXFT_Get_Face_Internal_Flag(m_Face);
- FXFT_Set_Transform(m_Face, &ft_matrix, 0);
- int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT) ? FXFT_LOAD_NO_BITMAP : FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING;
- int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
- if (error) {
- FXFT_Set_Face_Internal_Flag(m_Face, transflag);
- return NULL;
- }
- if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && m_pSubstFont->m_Weight > 400) {
- int level = 0;
- if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) {
- level = g_WeightPow_SHIFTJIS[(m_pSubstFont->m_Weight - 400) / 10] * 2 * 65536 / 36655;
- } else {
- level = g_WeightPow[(m_pSubstFont->m_Weight - 400) / 10] * 2;
- }
- FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
- }
- FXFT_Outline_Funcs funcs;
- funcs.move_to = _Outline_MoveTo;
- funcs.line_to = _Outline_LineTo;
- funcs.conic_to = _Outline_ConicTo;
- funcs.cubic_to = _Outline_CubicTo;
- funcs.shift = 0;
- funcs.delta = 0;
- OUTLINE_PARAMS params;
- params.m_bCount = TRUE;
- params.m_PointCount = 0;
- FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
- if (params.m_PointCount == 0) {
- FXFT_Set_Face_Internal_Flag(m_Face, transflag);
- return NULL;
- }
- CFX_PathData* pPath = FX_NEW CFX_PathData;
- if (!pPath) {
- return NULL;
- }
- pPath->SetPointCount(params.m_PointCount);
- params.m_bCount = FALSE;
- params.m_PointCount = 0;
- params.m_pPoints = pPath->GetPoints();
- params.m_CurX = params.m_CurY = 0;
- params.m_CoordUnit = 64 * 64.0;
- FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
- _Outline_CheckEmptyContour(&params);
- pPath->TrimPoints(params.m_PointCount);
- if (params.m_PointCount) {
- pPath->GetPoints()[params.m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
- }
- FXFT_Set_Face_Internal_Flag(m_Face, transflag);
- return pPath;
-}
-void _CFX_UniqueKeyGen::Generate(int count, ...)
-{
- va_list argList;
- va_start(argList, count);
- for (int i = 0; i < count; i ++) {
- int p = va_arg(argList, int);
- ((FX_DWORD*)m_Key)[i] = p;
- }
- va_end(argList);
- m_KeyLen = count * sizeof(FX_DWORD);
-}
+// 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 "../../../include/fxge/fx_ge.h"
+#include "../../../include/fxge/fx_freetype.h"
+#include "../../../include/fxcodec/fx_codec.h"
+#include "text_int.h"
+#undef FX_GAMMA
+#undef FX_GAMMA_INVERSE
+#define FX_GAMMA(value) (value)
+#define FX_GAMMA_INVERSE(value) (value)
+FX_RECT FXGE_GetGlyphsBBox(FXTEXT_GLYPHPOS* pGlyphAndPos, int nChars, int anti_alias, FX_FLOAT retinaScaleX, FX_FLOAT retinaScaleY)
+{
+ FX_RECT rect(0, 0, 0, 0);
+ FX_BOOL bStarted = FALSE;
+ for (int iChar = 0; iChar < nChars; iChar ++) {
+ FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
+ const CFX_GlyphBitmap* pGlyph = glyph.m_pGlyph;
+ if (pGlyph == NULL) {
+ continue;
+ }
+ int char_left = glyph.m_OriginX + pGlyph->m_Left;
+ int char_width = (int)(pGlyph->m_Bitmap.GetWidth() / retinaScaleX);
+ if (anti_alias == FXFT_RENDER_MODE_LCD) {
+ char_width /= 3;
+ }
+ int char_right = char_left + char_width;
+ int char_top = glyph.m_OriginY - pGlyph->m_Top;
+ int char_bottom = char_top + (int)(pGlyph->m_Bitmap.GetHeight() / retinaScaleY);
+ if (!bStarted) {
+ rect.left = char_left;
+ rect.right = char_right;
+ rect.top = char_top;
+ rect.bottom = char_bottom;
+ bStarted = TRUE;
+ } else {
+ if (rect.left > char_left) {
+ rect.left = char_left;
+ }
+ if (rect.right < char_right) {
+ rect.right = char_right;
+ }
+ if (rect.top > char_top) {
+ rect.top = char_top;
+ }
+ if (rect.bottom < char_bottom) {
+ rect.bottom = char_bottom;
+ }
+ }
+ }
+ return rect;
+}
+static void _AdjustGlyphSpace(FXTEXT_GLYPHPOS* pGlyphAndPos, int nChars)
+{
+ ASSERT(nChars > 1);
+ FX_BOOL bVertical = FALSE;
+ if (pGlyphAndPos[nChars - 1].m_OriginX == pGlyphAndPos[0].m_OriginX) {
+ bVertical = TRUE;
+ } else if (pGlyphAndPos[nChars - 1].m_OriginY != pGlyphAndPos[0].m_OriginY) {
+ return;
+ }
+ int i = nChars - 1;
+ int* next_origin = bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPos[i].m_OriginX;
+ FX_FLOAT next_origin_f = bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyphAndPos[i].m_fOriginX;
+ for (i --; i > 0; i --) {
+ int* this_origin = bVertical ? &pGlyphAndPos[i].m_OriginY : &pGlyphAndPos[i].m_OriginX;
+ FX_FLOAT this_origin_f = bVertical ? pGlyphAndPos[i].m_fOriginY : pGlyphAndPos[i].m_fOriginX;
+ int space = (*next_origin) - (*this_origin);
+ FX_FLOAT space_f = next_origin_f - this_origin_f;
+ FX_FLOAT error = (FX_FLOAT)(FXSYS_fabs(space_f) - FXSYS_fabs((FX_FLOAT)(space)));
+ if (error > 0.5f) {
+ *this_origin += space > 0 ? -1 : 1;
+ }
+ next_origin = this_origin;
+ next_origin_f = this_origin_f;
+ }
+}
+static const FX_BYTE g_GdipGamma_bgw[9] = {0, 0, 63, 120, 0, 168, 210, 239, 255};
+static const FX_BYTE g_GdipGamma_fgw[9] = {0, 0, 16, 45, 0, 87, 135, 192, 255};
+static const FX_BYTE g_GdipGammaAdjust_47[48] = {
+ 0, 30, 33, 34, 35, 36, 37, 38, 38, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42, 42, 43,
+ 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 46,
+ 46, 46, 46, 46, 46, 46, 46, 47
+};
+static const FX_BYTE g_GdipGammaAdjust_75[76] = {
+ 0, 46, 50, 52, 54, 55, 56, 57, 58, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 64, 65,
+ 65, 65, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 68, 69, 69, 69, 69, 69, 70, 70, 70,
+ 70, 70, 71, 71, 71, 71, 71, 71, 72, 72, 72, 72, 72, 72, 72, 73, 73, 73, 73, 73, 73, 73,
+ 73, 74, 74, 74, 74, 74, 74, 74, 74, 75
+};
+static const FX_BYTE g_GdipGammaAdjust_81[82] = {
+ 0, 49, 53, 56, 58, 59, 60, 61, 62, 63, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 69, 70, 70, 70,
+ 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, 76, 76, 76, 76,
+ 76, 76, 77, 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 80,
+ 80, 80, 80, 80, 80, 80, 80, 81
+};
+static void _Adjust_alpha(int background, int foreground, int& src_alpha, int text_flags, int a)
+{
+}
+static const FX_BYTE g_TextGammaAdjust[256] = {
+ 0, 2, 3, 4, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 19,
+ 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 33, 34, 35, 36, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 71, 72,
+ 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
+ 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
+ 121, 122, 123, 124, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
+ 167, 168, 169, 170, 171, 172, 173, 174, 174, 175, 176, 177, 178, 179, 180, 181,
+ 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 193, 194, 195, 196,
+ 197, 198, 199, 200, 201, 202, 203, 204, 204, 205, 206, 207, 208, 209, 210, 211,
+ 212, 213, 214, 215, 216, 217, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226,
+ 227, 228, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 239, 240,
+ 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 250, 251, 252, 253, 254, 255,
+};
+#define ADJUST_ALPHA(background, foreground, src_alpha, text_flags, a) \
+ src_alpha = g_TextGammaAdjust[(FX_BYTE)src_alpha];
+void _Color2Argb(FX_ARGB& argb, FX_DWORD color, int alpha_flag, void* pIccTransform)
+{
+ if (pIccTransform == NULL && !FXGETFLAG_COLORTYPE(alpha_flag)) {
+ argb = color;
+ return;
+ }
+ if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
+ pIccTransform = NULL;
+ }
+ FX_BYTE bgra[4];
+ if (pIccTransform) {
+ ICodec_IccModule* pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
+ color = FXGETFLAG_COLORTYPE(alpha_flag) ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
+ pIccModule->TranslateScanline(pIccTransform, bgra, (FX_LPCBYTE)&color, 1);
+ bgra[3] = FXGETFLAG_COLORTYPE(alpha_flag) ?
+ (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXGETFLAG_ALPHA_STROKE(alpha_flag) :
+ FXARGB_A(color);
+ argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]);
+ return;
+ }
+ AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color),
+ FXSYS_GetYValue(color), FXSYS_GetKValue(color),
+ bgra[2], bgra[1], bgra[0]);
+ bgra[3] = (alpha_flag >> 24) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXGETFLAG_ALPHA_STROKE(alpha_flag);
+ argb = FXARGB_MAKE(bgra[3], bgra[2], bgra[1], bgra[0]);
+}
+FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars, const FXTEXT_CHARPOS* pCharPos,
+ CFX_Font* pFont, CFX_FontCache* pCache,
+ FX_FLOAT font_size, const CFX_AffineMatrix* pText2Device,
+ FX_DWORD fill_color, FX_DWORD text_flags,
+ int alpha_flag, void* pIccTransform)
+{
+ int nativetext_flags = text_flags;
+ if (m_DeviceClass != FXDC_DISPLAY) {
+ if (!(text_flags & FXTEXT_PRINTGRAPHICTEXT)) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (!(text_flags & FXFONT_CIDFONT) && pFont->GetPsName().Find(CFX_WideString::FromLocal("+ZJHL")) == -1)
+#ifdef FOXIT_CHROME_BUILD
+ if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10"))
+#endif
+#endif
+ if (m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, pText2Device, font_size, fill_color, alpha_flag, pIccTransform)) {
+ return TRUE;
+ }
+ }
+ int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(fill_color);
+ if (alpha < 255) {
+ return FALSE;
+ }
+ } else if (!(text_flags & FXTEXT_NO_NATIVETEXT)) {
+#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
+ if (!(text_flags & FXFONT_CIDFONT))
+#ifdef FOXIT_CHROME_BUILD
+ if (pFont->GetPsName() != CFX_WideString::FromLocal("CNAAJI+cmex10"))
+#endif
+#endif
+ if (m_pDeviceDriver->DrawDeviceText(nChars, pCharPos, pFont, pCache, pText2Device, font_size, fill_color, alpha_flag, pIccTransform)) {
+ return TRUE;
+ }
+ }
+ CFX_AffineMatrix char2device, deviceCtm, text2Device;
+ if (pText2Device) {
+ char2device = *pText2Device;
+ text2Device = *pText2Device;
+ }
+ char2device.Scale(font_size, -font_size);
+ if (FXSYS_fabs(char2device.a) + FXSYS_fabs(char2device.b) > 50 * 1.0f ||
+ ((m_DeviceClass == FXDC_PRINTER && !m_pDeviceDriver->IsPSPrintDriver())
+ && !(text_flags & FXTEXT_PRINTIMAGETEXT))) {
+ if (pFont->GetFace() != NULL || (pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) {
+ int nPathFlags = (text_flags & FXTEXT_NOSMOOTH) == 0 ? 0 : FXFILL_NOPATHSMOOTH;
+ return DrawTextPath(nChars, pCharPos, pFont, pCache, font_size, pText2Device, NULL, NULL, fill_color, 0, NULL, nPathFlags, alpha_flag, pIccTransform);
+ }
+ }
+ int anti_alias = FXFT_RENDER_MODE_MONO;
+ FX_BOOL bNormal = FALSE;
+ if ((text_flags & FXTEXT_NOSMOOTH) == 0) {
+ if (m_DeviceClass == FXDC_DISPLAY && m_bpp > 1) {
+ FX_BOOL bClearType;
+ if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_CLEARTYPE)) {
+ bClearType = FALSE;
+ } else {
+ bClearType = text_flags & FXTEXT_CLEARTYPE;
+ }
+ if ((m_RenderCaps & (FXRC_ALPHA_OUTPUT | FXRC_CMYK_OUTPUT))) {
+ anti_alias = FXFT_RENDER_MODE_LCD;
+ bNormal = TRUE;
+ } else if (m_bpp < 16) {
+ anti_alias = FXFT_RENDER_MODE_NORMAL;
+ } else {
+ if (bClearType == FALSE) {
+ anti_alias = FXFT_RENDER_MODE_LCD;
+ bNormal = TRUE;
+ } else {
+ anti_alias = FXFT_RENDER_MODE_LCD;
+ }
+ }
+ }
+ }
+ if (pCache == NULL) {
+ pCache = CFX_GEModule::Get()->GetFontCache();
+ }
+ CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
+ FX_FONTCACHE_DEFINE(pCache, pFont);
+ FXTEXT_GLYPHPOS* pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, nChars);
+ if (!pGlyphAndPos) {
+ return FALSE;
+ }
+ int iChar;
+ deviceCtm = char2device;
+ CFX_AffineMatrix matrixCTM = GetCTM();
+ FX_FLOAT scale_x = FXSYS_fabs(matrixCTM.a);
+ FX_FLOAT scale_y = FXSYS_fabs(matrixCTM.d);
+ deviceCtm.Concat(scale_x, 0, 0, scale_y, 0, 0);
+ text2Device.Concat(scale_x, 0, 0, scale_y, 0, 0);
+ for (iChar = 0; iChar < nChars; iChar ++) {
+ FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
+ const FXTEXT_CHARPOS& charpos = pCharPos[iChar];
+ glyph.m_fOriginX = charpos.m_OriginX;
+ glyph.m_fOriginY = charpos.m_OriginY;
+ text2Device.Transform(glyph.m_fOriginX, glyph.m_fOriginY);
+ if (anti_alias < FXFT_RENDER_MODE_LCD) {
+ glyph.m_OriginX = FXSYS_round(glyph.m_fOriginX);
+ } else {
+ glyph.m_OriginX = (int)FXSYS_floor(glyph.m_fOriginX);
+ }
+ glyph.m_OriginY = FXSYS_round(glyph.m_fOriginY);
+ if (charpos.m_bGlyphAdjust) {
+ CFX_AffineMatrix new_matrix(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1],
+ charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0);
+ new_matrix.Concat(deviceCtm);
+ glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont, charpos.m_GlyphIndex, charpos.m_bFontStyle, &new_matrix,
+ charpos.m_FontCharWidth, anti_alias, nativetext_flags);
+ } else
+ glyph.m_pGlyph = pFaceCache->LoadGlyphBitmap(pFont, charpos.m_GlyphIndex, charpos.m_bFontStyle, &deviceCtm,
+ charpos.m_FontCharWidth, anti_alias, nativetext_flags);
+ }
+ if (anti_alias < FXFT_RENDER_MODE_LCD && nChars > 1) {
+ _AdjustGlyphSpace(pGlyphAndPos, nChars);
+ }
+ FX_RECT bmp_rect1 = FXGE_GetGlyphsBBox(pGlyphAndPos, nChars, anti_alias);
+ if (scale_x > 1 && scale_y > 1) {
+ bmp_rect1.left--;
+ bmp_rect1.top --;
+ bmp_rect1.right ++;
+ bmp_rect1.bottom ++;
+ }
+ FX_RECT bmp_rect(FXSYS_round((FX_FLOAT)(bmp_rect1.left) / scale_x), FXSYS_round((FX_FLOAT)(bmp_rect1.top) / scale_y),
+ FXSYS_round((FX_FLOAT)bmp_rect1.right / scale_x), FXSYS_round((FX_FLOAT)bmp_rect1.bottom / scale_y));
+ bmp_rect.Intersect(m_ClipBox);
+ if (bmp_rect.IsEmpty()) {
+ FX_Free(pGlyphAndPos);
+ return TRUE;
+ }
+ int pixel_width = FXSYS_round(bmp_rect.Width() * scale_x);
+ int pixel_height = FXSYS_round(bmp_rect.Height() * scale_y);
+ int pixel_left = FXSYS_round(bmp_rect.left * scale_x);
+ int pixel_top = FXSYS_round(bmp_rect.top * scale_y);
+ if (anti_alias == FXFT_RENDER_MODE_MONO) {
+ CFX_DIBitmap bitmap;
+ if (!bitmap.Create(pixel_width, pixel_height, FXDIB_1bppMask)) {
+ FX_Free(pGlyphAndPos);
+ return FALSE;
+ }
+ bitmap.Clear(0);
+ for (iChar = 0; iChar < nChars; iChar ++) {
+ FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
+ if (glyph.m_pGlyph == NULL) {
+ continue;
+ }
+ const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
+ bitmap.TransferBitmap(glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left,
+ glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top,
+ pGlyph->GetWidth(), pGlyph->GetHeight(), pGlyph, 0, 0);
+ }
+ FX_Free(pGlyphAndPos);
+ return SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color);
+ }
+ CFX_DIBitmap bitmap;
+ if (m_bpp == 8) {
+ if (!bitmap.Create(pixel_width, pixel_height, FXDIB_8bppMask)) {
+ FX_Free(pGlyphAndPos);
+ return FALSE;
+ }
+ } else {
+ if (!CreateCompatibleBitmap(&bitmap, pixel_width, pixel_height)) {
+ FX_Free(pGlyphAndPos);
+ return FALSE;
+ }
+ }
+ if (!bitmap.HasAlpha() && !bitmap.IsAlphaMask()) {
+ bitmap.Clear(0xFFFFFFFF);
+ if (!GetDIBits(&bitmap, bmp_rect.left, bmp_rect.top)) {
+ FX_Free(pGlyphAndPos);
+ return FALSE;
+ }
+ } else {
+ bitmap.Clear(0);
+ if (bitmap.m_pAlphaMask) {
+ bitmap.m_pAlphaMask->Clear(0);
+ }
+ }
+ int dest_width = pixel_width;
+ FX_LPBYTE dest_buf = bitmap.GetBuffer();
+ int dest_pitch = bitmap.GetPitch();
+ int Bpp = bitmap.GetBPP() / 8;
+ int a, r, g, b;
+ if (anti_alias == FXFT_RENDER_MODE_LCD) {
+ _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
+ ArgbDecode(fill_color, a, r, g, b);
+ r = FX_GAMMA(r);
+ g = FX_GAMMA(g);
+ b = FX_GAMMA(b);
+ }
+ for (iChar = 0; iChar < nChars; iChar ++) {
+ FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar];
+ if (glyph.m_pGlyph == NULL) {
+ continue;
+ }
+ const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
+ int left = glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left;
+ int top = glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top;
+ int ncols = pGlyph->GetWidth();
+ int nrows = pGlyph->GetHeight();
+ if (anti_alias == FXFT_RENDER_MODE_NORMAL) {
+ if (!bitmap.CompositeMask(left, top, ncols, nrows, pGlyph, fill_color,
+ 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) {
+ FX_Free(pGlyphAndPos);
+ return FALSE;
+ }
+ continue;
+ }
+ FX_BOOL bBGRStripe = text_flags & FXTEXT_BGR_STRIPE;
+ ncols /= 3;
+ int x_subpixel = (int)(glyph.m_fOriginX * 3) % 3;
+ FX_LPBYTE src_buf = pGlyph->GetBuffer();
+ int src_pitch = pGlyph->GetPitch();
+ int start_col = left;
+ if (start_col < 0) {
+ start_col = 0;
+ }
+ int end_col = left + ncols;
+ if (end_col > dest_width) {
+ end_col = dest_width;
+ }
+ if (start_col >= end_col) {
+ continue;
+ }
+ if (bitmap.GetFormat() == FXDIB_Argb) {
+ for (int row = 0; row < nrows; row ++) {
+ int dest_row = row + top;
+ if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
+ continue;
+ }
+ FX_LPBYTE src_scan = src_buf + row * src_pitch + (start_col - left) * 3;
+ FX_LPBYTE dest_scan = dest_buf + dest_row * dest_pitch + (start_col << 2);
+ if (bBGRStripe) {
+ if (x_subpixel == 0) {
+ for (int col = start_col; col < end_col; col ++) {
+ int src_alpha = src_scan[2];
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[1];
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[0];
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ } else if (x_subpixel == 1) {
+ int src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ if (start_col > left) {
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ }
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ for (int col = start_col + 1; col < end_col - 1; col ++) {
+ int src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ } else {
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ if (start_col > left) {
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[-2];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ }
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ for (int col = start_col + 1; col < end_col - 1; col ++) {
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[-2];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ }
+ } else {
+ if (x_subpixel == 0) {
+ for (int col = start_col; col < end_col; col ++) {
+ if (bNormal) {
+ int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[2]) / 3;
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ if (src_alpha1 == 0) {
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha1 * 255 / dest_alpha;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[2];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ } else if (x_subpixel == 1) {
+ if (bNormal) {
+ int src_alpha1 = start_col > left ? ((src_scan[-1] + src_scan[0] + src_scan[1]) / 3) : ((src_scan[0] + src_scan[1]) / 3);
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ if (src_alpha1 == 0) {
+ dest_scan += 4;
+ src_scan += 3;
+ } else {
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
+ } else {
+ FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha1 * 255 / dest_alpha;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
+ }
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ } else {
+ if (start_col > left) {
+ int src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ }
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ for (int col = start_col + 1; col < end_col; col ++) {
+ if (bNormal) {
+ int src_alpha1 = (src_scan[-1] + src_scan[0] + src_scan[1]) / 3;
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ if (src_alpha1 == 0) {
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha1 * 255 / dest_alpha;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ int src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ } else {
+ if (bNormal) {
+ int src_alpha1 = start_col > left ? ((src_scan[-2] + src_scan[-1] + src_scan[0]) / 3) : ((src_scan[0]) / 3);
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ if (src_alpha1 == 0) {
+ dest_scan += 4;
+ src_scan += 3;
+ } else {
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
+ } else {
+ FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha1 * 255 / dest_alpha;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
+ }
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ } else {
+ if (start_col > left) {
+ int src_alpha = src_scan[-2];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ }
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ for (int col = start_col + 1; col < end_col; col ++) {
+ if (bNormal) {
+ int src_alpha1 = (src_scan[-2] + src_scan[-1] + src_scan[0]) / 3;
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ FX_BYTE back_alpha = dest_scan[3];
+ if (back_alpha == 0) {
+ FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_alpha1, r, g, b));
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ if (src_alpha1 == 0) {
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ FX_BYTE dest_alpha = back_alpha + src_alpha1 - back_alpha * src_alpha1 / 255;
+ dest_scan[3] = dest_alpha;
+ int alpha_ratio = src_alpha1 * 255 / dest_alpha;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, alpha_ratio));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, alpha_ratio));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, alpha_ratio));
+ dest_scan += 4;
+ src_scan += 3;
+ continue;
+ }
+ int src_alpha = src_scan[-2];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ src_scan += 3;
+ }
+ }
+ }
+ }
+ } else {
+ for (int row = 0; row < nrows; row ++) {
+ int dest_row = row + top;
+ if (dest_row < 0 || dest_row >= bitmap.GetHeight()) {
+ continue;
+ }
+ FX_LPBYTE src_scan = src_buf + row * src_pitch + (start_col - left) * 3;
+ FX_LPBYTE dest_scan = dest_buf + dest_row * dest_pitch + start_col * Bpp;
+ if (bBGRStripe) {
+ if (x_subpixel == 0) {
+ for (int col = start_col; col < end_col; col ++) {
+ int src_alpha = src_scan[2];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan += Bpp;
+ src_scan += 3;
+ }
+ } else if (x_subpixel == 1) {
+ int src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ if (start_col > left) {
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ }
+ dest_scan += Bpp;
+ src_scan += 3;
+ for (int col = start_col + 1; col < end_col - 1; col ++) {
+ int src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan += Bpp;
+ src_scan += 3;
+ }
+ } else {
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ if (start_col > left) {
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[-2];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ }
+ dest_scan += Bpp;
+ src_scan += 3;
+ for (int col = start_col + 1; col < end_col - 1; col ++) {
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[-2];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan += Bpp;
+ src_scan += 3;
+ }
+ }
+ } else {
+ if (x_subpixel == 0) {
+ for (int col = start_col; col < end_col; col ++) {
+ if (bNormal) {
+ int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[2]) / 3;
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ if (src_alpha1 == 0) {
+ dest_scan += Bpp;
+ src_scan += 3;
+ continue;
+ }
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
+ dest_scan += Bpp;
+ src_scan += 3;
+ continue;
+ }
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[2];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan += Bpp;
+ src_scan += 3;
+ }
+ } else if (x_subpixel == 1) {
+ if (bNormal) {
+ int src_alpha1 = start_col > left ? (src_scan[0] + src_scan[1] + src_scan[-1]) / 3 : (src_scan[0] + src_scan[1]) / 3;
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
+ dest_scan += Bpp;
+ src_scan += 3;
+ } else {
+ if (start_col > left) {
+ int src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ }
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan += Bpp;
+ src_scan += 3;
+ }
+ for (int col = start_col + 1; col < end_col; col ++) {
+ if (bNormal) {
+ int src_alpha1 = (src_scan[0] + src_scan[1] + src_scan[-1]) / 3;
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ if (src_alpha1 == 0) {
+ dest_scan += Bpp;
+ src_scan += 3;
+ continue;
+ }
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
+ dest_scan += Bpp;
+ src_scan += 3;
+ continue;
+ }
+ int src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[1];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan += Bpp;
+ src_scan += 3;
+ }
+ } else {
+ if (bNormal) {
+ int src_alpha1 = start_col > left ? (src_scan[0] + src_scan[-2] + src_scan[-1]) / 3 : src_scan[0] / 3;
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
+ dest_scan += Bpp;
+ src_scan += 3;
+ } else {
+ if (start_col > left) {
+ int src_alpha = src_scan[-2];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ }
+ int src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan += Bpp;
+ src_scan += 3;
+ }
+ for (int col = start_col + 1; col < end_col; col ++) {
+ if (bNormal) {
+ int src_alpha1 = ((int)(src_scan[0]) + (int)(src_scan[-2]) + (int)(src_scan[-1])) / 3;
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha1, nativetext_flags, a);
+ src_alpha1 = src_alpha1 * a / 255;
+ if (src_alpha1 == 0) {
+ dest_scan += Bpp;
+ src_scan += 3;
+ continue;
+ }
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha1));
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha1));
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha1));
+ dest_scan += Bpp;
+ src_scan += 3;
+ continue;
+ }
+ int src_alpha = src_scan[-2];
+ ADJUST_ALPHA(dest_scan[2], r, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[2] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[2]), r, src_alpha));
+ src_alpha = src_scan[-1];
+ ADJUST_ALPHA(dest_scan[1], g, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[1] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[1]), g, src_alpha));
+ src_alpha = src_scan[0];
+ ADJUST_ALPHA(dest_scan[0], b, src_alpha, nativetext_flags, a);
+ src_alpha = src_alpha * a / 255;
+ dest_scan[0] = FX_GAMMA_INVERSE(FXDIB_ALPHA_MERGE(FX_GAMMA(dest_scan[0]), b, src_alpha));
+ dest_scan += Bpp;
+ src_scan += 3;
+ }
+ }
+ }
+ }
+ }
+ }
+ if (bitmap.IsAlphaMask()) {
+ SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color, alpha_flag, pIccTransform);
+ } else {
+ SetDIBits(&bitmap, bmp_rect.left, bmp_rect.top);
+ }
+ FX_Free(pGlyphAndPos);
+ return TRUE;
+}
+FX_BOOL CFX_RenderDevice::DrawTextPath(int nChars, const FXTEXT_CHARPOS* pCharPos,
+ CFX_Font* pFont, CFX_FontCache* pCache,
+ FX_FLOAT font_size, const CFX_AffineMatrix* pText2User,
+ const CFX_AffineMatrix* pUser2Device, const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color, FX_ARGB stroke_color, CFX_PathData* pClippingPath, int nFlag,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (pCache == NULL) {
+ pCache = CFX_GEModule::Get()->GetFontCache();
+ }
+ CFX_FaceCache* pFaceCache = pCache->GetCachedFace(pFont);
+ FX_FONTCACHE_DEFINE(pCache, pFont);
+ for (int iChar = 0; iChar < nChars; iChar ++) {
+ const FXTEXT_CHARPOS& charpos = pCharPos[iChar];
+ CFX_AffineMatrix matrix;
+ if (charpos.m_bGlyphAdjust)
+ matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1],
+ charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0);
+ matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, charpos.m_OriginY);
+ const CFX_PathData* pPath = pFaceCache->LoadGlyphPath(pFont, charpos.m_GlyphIndex, charpos.m_FontCharWidth);
+ if (pPath == NULL) {
+ continue;
+ }
+ matrix.Concat(*pText2User);
+ CFX_PathData TransformedPath(*pPath);
+ TransformedPath.Transform(&matrix);
+ FX_BOOL bHasAlpha = FXGETFLAG_COLORTYPE(alpha_flag) ?
+ (FXGETFLAG_ALPHA_FILL(alpha_flag) || FXGETFLAG_ALPHA_STROKE(alpha_flag)) :
+ (fill_color || stroke_color);
+ if (bHasAlpha) {
+ int fill_mode = nFlag;
+ if (FXGETFLAG_COLORTYPE(alpha_flag)) {
+ if (FXGETFLAG_ALPHA_FILL(alpha_flag)) {
+ fill_mode |= FXFILL_WINDING;
+ }
+ } else {
+ if (fill_color) {
+ fill_mode |= FXFILL_WINDING;
+ }
+ }
+ fill_mode |= FX_FILL_TEXT_MODE;
+ if (!DrawPath(&TransformedPath, pUser2Device, pGraphState, fill_color, stroke_color, fill_mode, alpha_flag, pIccTransform, blend_type)) {
+ return FALSE;
+ }
+ }
+ if (pClippingPath) {
+ pClippingPath->Append(&TransformedPath, pUser2Device);
+ }
+ }
+ return TRUE;
+}
+CFX_FontCache::~CFX_FontCache()
+{
+ FreeCache(TRUE);
+}
+CFX_FaceCache* CFX_FontCache::GetCachedFace(CFX_Font* pFont)
+{
+ FX_BOOL bExternal = pFont->GetFace() == NULL;
+ void* face = bExternal ? pFont->GetSubstFont()->m_ExtHandle : pFont->GetFace();
+ CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap;
+ CFX_CountedFaceCache* counted_face_cache = NULL;
+ if (map.Lookup((FXFT_Face)face, counted_face_cache)) {
+ counted_face_cache->m_nCount++;
+ return counted_face_cache->m_Obj;
+ }
+ CFX_FaceCache* face_cache = NULL;
+ face_cache = FX_NEW CFX_FaceCache(bExternal ? NULL : (FXFT_Face)face);
+ if (face_cache == NULL) {
+ return NULL;
+ }
+ counted_face_cache = FX_NEW CFX_CountedFaceCache;
+ if (!counted_face_cache) {
+ if (face_cache) {
+ delete face_cache;
+ face_cache = NULL;
+ }
+ return NULL;
+ }
+ counted_face_cache->m_nCount = 2;
+ counted_face_cache->m_Obj = face_cache;
+ map.SetAt((FXFT_Face)face, counted_face_cache);
+ return face_cache;
+}
+void CFX_FontCache::ReleaseCachedFace(CFX_Font* pFont)
+{
+ FX_BOOL bExternal = pFont->GetFace() == NULL;
+ void* face = bExternal ? pFont->GetSubstFont()->m_ExtHandle : pFont->GetFace();
+ CFX_FTCacheMap& map = bExternal ? m_ExtFaceMap : m_FTFaceMap;
+ CFX_CountedFaceCache* counted_face_cache = NULL;
+ if (!map.Lookup((FXFT_Face)face, counted_face_cache)) {
+ return;
+ }
+ if (counted_face_cache->m_nCount > 1) {
+ counted_face_cache->m_nCount--;
+ }
+}
+void CFX_FontCache::FreeCache(FX_BOOL bRelease)
+{
+ {
+ FX_POSITION pos;
+ pos = m_FTFaceMap.GetStartPosition();
+ while (pos) {
+ FXFT_Face face;
+ CFX_CountedFaceCache* cache;
+ m_FTFaceMap.GetNextAssoc(pos, face, cache);
+ if (bRelease || cache->m_nCount < 2) {
+ delete cache->m_Obj;
+ delete cache;
+ m_FTFaceMap.RemoveKey(face);
+ }
+ }
+ pos = m_ExtFaceMap.GetStartPosition();
+ while (pos) {
+ FXFT_Face face;
+ CFX_CountedFaceCache* cache;
+ m_ExtFaceMap.GetNextAssoc(pos, face, cache);
+ if (bRelease || cache->m_nCount < 2) {
+ delete cache->m_Obj;
+ delete cache;
+ m_ExtFaceMap.RemoveKey(face);
+ }
+ }
+ }
+}
+CFX_FaceCache::CFX_FaceCache(FXFT_Face face)
+{
+ m_Face = face;
+ m_pBitmap = NULL;
+}
+CFX_FaceCache::~CFX_FaceCache()
+{
+ FX_POSITION pos = m_SizeMap.GetStartPosition();
+ CFX_ByteString Key;
+ CFX_SizeGlyphCache* pSizeCache = NULL;
+ while(pos) {
+ m_SizeMap.GetNextAssoc( pos, Key, (void*&)pSizeCache);
+ delete pSizeCache;
+ }
+ m_SizeMap.RemoveAll();
+ pos = m_PathMap.GetStartPosition();
+ FX_LPVOID key1;
+ CFX_PathData* pPath;
+ while (pos) {
+ m_PathMap.GetNextAssoc(pos, key1, (FX_LPVOID&)pPath);
+ delete pPath;
+ }
+ if (m_pBitmap) {
+ delete m_pBitmap;
+ }
+ m_PathMap.RemoveAll();
+}
+#if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_)|| defined(_FPDFAPI_MINI_))
+void CFX_FaceCache::InitPlatform()
+{
+}
+#endif
+CFX_GlyphBitmap* CFX_FaceCache::LookUpGlyphBitmap(CFX_Font* pFont, const CFX_AffineMatrix* pMatrix,
+ CFX_ByteStringC& FaceGlyphsKey, FX_DWORD glyph_index, FX_BOOL bFontStyle,
+ int dest_width, int anti_alias)
+{
+ CFX_SizeGlyphCache* pSizeCache = NULL;
+ if (!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
+ pSizeCache = FX_NEW CFX_SizeGlyphCache;
+ if (pSizeCache == NULL) {
+ return NULL;
+ }
+ m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
+ }
+ CFX_GlyphBitmap* pGlyphBitmap = NULL;
+ if (pSizeCache->m_GlyphMap.Lookup((FX_LPVOID)(FX_UINTPTR)glyph_index, (void*&)pGlyphBitmap)) {
+ return pGlyphBitmap;
+ }
+ pGlyphBitmap = RenderGlyph(pFont, glyph_index, bFontStyle, pMatrix, dest_width, anti_alias);
+ if (pGlyphBitmap == NULL) {
+ return NULL;
+ }
+ pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)glyph_index, pGlyphBitmap);
+ return pGlyphBitmap;
+}
+const CFX_GlyphBitmap* CFX_FaceCache::LoadGlyphBitmap(CFX_Font* pFont, FX_DWORD glyph_index, FX_BOOL bFontStyle, const CFX_AffineMatrix* pMatrix,
+ int dest_width, int anti_alias, int& text_flags)
+{
+ if (glyph_index == (FX_DWORD) - 1) {
+ return NULL;
+ }
+ _CFX_UniqueKeyGen keygen;
+#if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_)|| defined(_FPDFAPI_MINI_))
+ if (pFont->GetSubstFont())
+ keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
+ (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias,
+ pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
+ else
+ keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
+ (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias);
+#else
+ if (text_flags & FXTEXT_NO_NATIVETEXT) {
+ if (pFont->GetSubstFont())
+ keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
+ (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias,
+ pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
+ else
+ keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
+ (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias);
+ } else {
+ if (pFont->GetSubstFont())
+ keygen.Generate(10, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
+ (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias,
+ pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical(), 3);
+ else
+ keygen.Generate(7, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
+ (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias, 3);
+ }
+#endif
+ CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
+#if ((_FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_)|| defined(_FPDFAPI_MINI_))
+ return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFontStyle, dest_width, anti_alias);
+#else
+ if (text_flags & FXTEXT_NO_NATIVETEXT) {
+ return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFontStyle, dest_width, anti_alias);
+ } else {
+ CFX_GlyphBitmap* pGlyphBitmap;
+ CFX_SizeGlyphCache* pSizeCache = NULL;
+ if (m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) {
+ if (pSizeCache->m_GlyphMap.Lookup((FX_LPVOID)(FX_UINTPTR)glyph_index, (void*&)pGlyphBitmap)) {
+ return pGlyphBitmap;
+ }
+ pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, dest_width, anti_alias);
+ if (pGlyphBitmap) {
+ pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)glyph_index, pGlyphBitmap);
+ return pGlyphBitmap;
+ }
+ } else {
+ pGlyphBitmap = RenderGlyph_Nativetext(pFont, glyph_index, pMatrix, dest_width, anti_alias);
+ if (pGlyphBitmap) {
+ pSizeCache = FX_NEW CFX_SizeGlyphCache;
+ if (pSizeCache == NULL) {
+ return NULL;
+ }
+ m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache);
+ pSizeCache->m_GlyphMap.SetAt((FX_LPVOID)(FX_UINTPTR)glyph_index, pGlyphBitmap);
+ return pGlyphBitmap;
+ }
+ }
+ if (pFont->GetSubstFont())
+ keygen.Generate(9, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
+ (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias,
+ pFont->GetSubstFont()->m_Weight, pFont->GetSubstFont()->m_ItalicAngle, pFont->IsVertical());
+ else
+ keygen.Generate(6, (int)(pMatrix->a * 10000), (int)(pMatrix->b * 10000),
+ (int)(pMatrix->c * 10000), (int)(pMatrix->d * 10000), dest_width, anti_alias);
+ CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen);
+ text_flags |= FXTEXT_NO_NATIVETEXT;
+ return LookUpGlyphBitmap(pFont, pMatrix, FaceGlyphsKey, glyph_index, bFontStyle, dest_width, anti_alias);
+ }
+#endif
+}
+CFX_SizeGlyphCache::~CFX_SizeGlyphCache()
+{
+ FX_POSITION pos = m_GlyphMap.GetStartPosition();
+ FX_LPVOID Key;
+ CFX_GlyphBitmap* pGlyphBitmap = NULL;
+ while(pos) {
+ m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap);
+ delete pGlyphBitmap;
+ }
+ m_GlyphMap.RemoveAll();
+}
+#if defined(_FPDFAPI_MINI_)
+#define CONTRAST_RAMP_STEP 16
+#else
+#define CONTRAST_RAMP_STEP 1
+#endif
+static const FX_BYTE g_adjust_contrast11[256] = {
+ 0, 0, 2, 3, 4, 5, 6, 8, 9, 10, 11, 13, 14, 15, 17, 18, 19, 21, 22, 24, 25, 26, 28, 29, 31,
+ 32, 33, 35, 36, 38, 39, 40, 42, 43, 45, 46, 48, 49, 51, 52, 54, 55, 56, 58, 59, 61, 62, 64, 65,
+ 67, 68, 70, 71, 72, 74, 75, 77, 78, 80, 81, 83, 84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 99, 100,
+ 101, 103, 104, 106, 107, 109, 110, 111, 113, 114, 116, 117, 118, 120, 121, 123, 124, 125, 127,
+ 128, 130, 131, 132, 134, 135, 136, 138, 139, 140, 142, 143, 144, 146, 147, 148, 149, 151, 152,
+ 153, 155, 156, 157, 158, 160, 161, 162, 163, 165, 166, 167, 168, 169, 171, 172, 173, 174, 175,
+ 177, 178, 179, 180, 181, 182, 183, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196,
+ 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215,
+ 215, 216, 217, 218, 219, 220, 221, 221, 222, 223, 224, 224, 225, 226, 227, 227, 228, 229, 230,
+ 230, 231, 232, 232, 233, 234, 234, 235, 236, 236, 237, 237, 238, 239, 239, 240, 240, 241, 241,
+ 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
+ 250, 250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 254, 254,
+ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255,
+};
+static const FX_BYTE g_adjust_contrast15[256] = {
+ 0, 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 40, 41, 42, 43, 45, 46, 47, 48, 50, 51,
+ 52, 54, 55, 56, 58, 59, 60, 62, 63, 64, 66, 67, 68, 70, 71, 73, 74, 75, 77, 78, 80, 81, 82, 84, 85, 87,
+ 88, 90, 91, 93, 94, 95, 97, 98, 100, 101, 103, 104, 106, 107, 109, 110, 111, 113, 114, 116, 117, 119,
+ 120, 122, 123, 125, 126, 128, 129, 130, 132, 133, 135, 136, 138, 139, 141, 142, 143, 145, 146, 148,
+ 149, 150, 152, 153, 155, 156, 157, 159, 160, 161, 163, 164, 166, 167, 168, 170, 171, 172, 174, 175,
+ 176, 177, 179, 180, 181, 183, 184, 185, 186, 188, 189, 190, 191, 192, 194, 195, 196, 197, 198, 199,
+ 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220,
+ 221, 222, 223, 224, 225, 226, 227, 227, 228, 229, 230, 231, 232, 232, 233, 234, 235, 235, 236, 237,
+ 237, 238, 239, 239, 240, 241, 241, 242, 242, 243, 244, 244, 245, 245, 246, 246, 247, 247, 248, 248,
+ 248, 249, 249, 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 253, 254, 254,
+ 254, 254, 254, 254, 254, 254, 254, 254, 254, 255,
+};
+static void _CalcContrastRamp(FX_LPBYTE ramp, int level)
+{
+ int contrast_min = 0, contrast_max = 255 - level, i;
+ for (i = 0; i < contrast_min; i ++) {
+ ramp[i] = 0;
+ }
+ for (i = contrast_min; i < contrast_max; i ++) {
+ ramp[i] = 255 * (i - contrast_min) / (contrast_max - contrast_min);
+ }
+ for (i = contrast_max; i < 256; i ++) {
+ ramp[i] = 255;
+ }
+}
+void CFX_Font::AdjustMMParams(int glyph_index, int dest_width, int weight)
+{
+ FXFT_MM_Var pMasters = NULL;
+ FXFT_Get_MM_Var(m_Face, &pMasters);
+ if (pMasters == NULL) {
+ return;
+ }
+ long coords[2];
+ if (weight == 0) {
+ coords[0] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 0)) / 65536;
+ } else {
+ coords[0] = weight;
+ }
+ if (dest_width == 0) {
+ coords[1] = FXFT_Get_MM_Axis_Def(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
+ } else {
+ int min_param = FXFT_Get_MM_Axis_Min(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
+ int max_param = FXFT_Get_MM_Axis_Max(FXFT_Get_MM_Axis(pMasters, 1)) / 65536;
+ coords[1] = min_param;
+ int error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
+ error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
+ int min_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / FXFT_Get_Face_UnitsPerEM(m_Face);
+ coords[1] = max_param;
+ error = FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
+ error = FXFT_Load_Glyph(m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
+ int max_width = FXFT_Get_Glyph_HoriAdvance(m_Face) * 1000 / FXFT_Get_Face_UnitsPerEM(m_Face);
+ if (max_width == min_width) {
+ return;
+ }
+ int param = min_param + (max_param - min_param) * (dest_width - min_width) / (max_width - min_width);
+ coords[1] = param;
+ }
+ FXFT_Free(m_Face, pMasters);
+ FXFT_Set_MM_Design_Coordinates(m_Face, 2, coords);
+}
+extern const char g_AngleSkew[30] = {
+ 0, 2, 3, 5, 7, 9, 11, 12, 14, 16,
+ 18, 19, 21, 23, 25, 27, 29, 31, 32, 34,
+ 36, 38, 40, 42, 45, 47, 49, 51, 53, 55,
+};
+static const FX_BYTE g_WeightPow[100] = {
+ 0, 3, 6, 7, 8, 9, 11, 12, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 36,
+ 37, 37, 37, 38, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41, 41, 42, 42, 42,
+ 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47,
+ 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51,
+ 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53,
+};
+extern const FX_BYTE g_WeightPow_11[100] = {
+ 0, 4, 7, 8, 9, 10, 12, 13, 15, 17, 18, 19, 20, 21, 22,
+ 23, 24, 25, 26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 39, 40, 40,
+ 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 45, 45, 45, 46, 46, 46,
+ 46, 43, 47, 47, 48, 48, 48, 48, 45, 50, 50, 50, 46, 51, 51, 51, 52, 52,
+ 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56,
+ 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 58,
+};
+extern const FX_BYTE g_WeightPow_SHIFTJIS[100] = {
+ 0, 0, 1, 2, 3, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 21, 22, 24, 26, 28,
+ 30, 32, 33, 35, 37, 39, 41, 43, 45, 48, 48, 48, 48, 49, 49, 49, 50, 50, 50, 50,
+ 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55,
+ 55, 55, 55, 56, 56, 56, 56, 56 , 56, 57, 57, 57 , 57 , 57, 57, 57, 58, 58, 58, 58, 58,
+ 58, 58, 59, 59, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60,
+};
+static void _GammaAdjust(FX_LPBYTE pData, int nWid, int nHei, int src_pitch, FX_LPCBYTE gammaTable)
+{
+ int count = nHei * src_pitch;
+ for(int i = 0; i < count; i++) {
+ pData[i] = gammaTable[pData[i]];
+ }
+}
+static void _ContrastAdjust(FX_LPBYTE pDataIn, FX_LPBYTE pDataOut, int nWid, int nHei, int nSrcRowBytes, int nDstRowBytes)
+{
+ int col, row, temp;
+ int max = 0, min = 255;
+ FX_FLOAT rate;
+ for (row = 0; row < nHei; row ++) {
+ FX_LPBYTE pRow = pDataIn + row * nSrcRowBytes;
+ for (col = 0; col < nWid; col++) {
+ temp = *pRow ++;
+ if (temp > max) {
+ max = temp;
+ }
+ if (temp < min) {
+ min = temp;
+ }
+ }
+ }
+ temp = max - min;
+ if (0 == temp || 255 == temp) {
+ int rowbytes = FXSYS_abs(nSrcRowBytes) > nDstRowBytes ? nDstRowBytes : FXSYS_abs(nSrcRowBytes);
+ for (row = 0; row < nHei; row ++) {
+ FXSYS_memcpy32(pDataOut + row * nDstRowBytes, pDataIn + row * nSrcRowBytes, rowbytes);
+ }
+ return;
+ }
+ rate = 255.f / temp;
+ for (row = 0; row < nHei; row ++) {
+ FX_LPBYTE pSrcRow = pDataIn + row * nSrcRowBytes;
+ FX_LPBYTE pDstRow = pDataOut + row * nDstRowBytes;
+ for (col = 0; col < nWid; col ++) {
+ temp = (int)((*(pSrcRow++) - min) * rate + 0.5);
+ if (temp > 255) {
+ temp = 255;
+ } else if (temp < 0) {
+ temp = 0;
+ }
+ *pDstRow ++ = (FX_BYTE)temp;
+ }
+ }
+}
+CFX_GlyphBitmap* CFX_FaceCache::RenderGlyph(CFX_Font* pFont, FX_DWORD glyph_index, FX_BOOL bFontStyle,
+ const CFX_AffineMatrix* pMatrix, int dest_width, int anti_alias)
+{
+ if (m_Face == NULL) {
+ return NULL;
+ }
+ FXFT_Matrix ft_matrix;
+ ft_matrix.xx = (signed long)(pMatrix->GetA() / 64 * 65536);
+ ft_matrix.xy = (signed long)(pMatrix->GetC() / 64 * 65536);
+ ft_matrix.yx = (signed long)(pMatrix->GetB() / 64 * 65536);
+ ft_matrix.yy = (signed long)(pMatrix->GetD() / 64 * 65536);
+ FX_BOOL bUseCJKSubFont = FALSE;
+ const CFX_SubstFont* pSubstFont = pFont->GetSubstFont();
+ if (pSubstFont) {
+ bUseCJKSubFont = pSubstFont->m_bSubstOfCJK && bFontStyle;
+ int skew = 0;
+ if (bUseCJKSubFont) {
+ skew = pSubstFont->m_bItlicCJK ? -15 : 0;
+ } else {
+ skew = pSubstFont->m_ItalicAngle;
+ }
+ if (skew) {
+ skew = skew <= -30 ? -58 : -g_AngleSkew[-skew];
+ if (pFont->IsVertical()) {
+ ft_matrix.yx += ft_matrix.yy * skew / 100;
+ } else {
+ ft_matrix.xy += -ft_matrix.xx * skew / 100;
+ }
+ }
+ if (pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
+ pFont->AdjustMMParams(glyph_index, dest_width, pFont->GetSubstFont()->m_Weight);
+ }
+ }
+ int transflag = FXFT_Get_Face_Internal_Flag(m_Face);
+ FXFT_Set_Transform(m_Face, &ft_matrix, 0);
+ int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT) ? FXFT_LOAD_NO_BITMAP : (FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
+ int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
+ if (error) {
+ FXFT_Set_Face_Internal_Flag(m_Face, transflag);
+ return NULL;
+ }
+ int weight = 0;
+ if (bUseCJKSubFont) {
+ weight = pSubstFont->m_WeightCJK;
+ } else {
+ weight = pSubstFont ? pSubstFont->m_Weight : 0;
+ }
+ if (pSubstFont && !(pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && weight > 400) {
+ int index = (weight - 400) / 10;
+ if (index >= 100) {
+ FXFT_Set_Face_Internal_Flag(m_Face, transflag);
+ return NULL;
+ }
+ int level = 0;
+ if (pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) {
+ level = g_WeightPow_SHIFTJIS[index] * 2 * (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) / 36655;
+ } else {
+ level = g_WeightPow_11[index] * (FXSYS_abs((int)(ft_matrix.xx)) + FXSYS_abs((int)(ft_matrix.xy))) / 36655;
+ }
+ FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
+ }
+ FXFT_Library_SetLcdFilter(CFX_GEModule::Get()->GetFontMgr()->m_FTLibrary, FT_LCD_FILTER_DEFAULT);
+ error = FXFT_Render_Glyph(m_Face, anti_alias);
+ if (error) {
+ FXFT_Set_Face_Internal_Flag(m_Face, transflag);
+ return NULL;
+ }
+ int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(m_Face));
+ int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(m_Face));
+ if (bmwidth > 2048 || bmheight > 2048) {
+ FXFT_Set_Face_Internal_Flag(m_Face, transflag);
+ return NULL;
+ }
+ int dib_width = bmwidth;
+ CFX_GlyphBitmap* pGlyphBitmap = FX_NEW CFX_GlyphBitmap;
+ if (!pGlyphBitmap) {
+ return NULL;
+ }
+ pGlyphBitmap->m_Bitmap.Create(dib_width, bmheight,
+ anti_alias == FXFT_RENDER_MODE_MONO ? FXDIB_1bppMask : FXDIB_8bppMask);
+ pGlyphBitmap->m_Left = FXFT_Get_Glyph_BitmapLeft(m_Face);
+ pGlyphBitmap->m_Top = FXFT_Get_Glyph_BitmapTop(m_Face);
+ int dest_pitch = pGlyphBitmap->m_Bitmap.GetPitch();
+ int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(m_Face));
+ FX_BYTE* pDestBuf = pGlyphBitmap->m_Bitmap.GetBuffer();
+ FX_BYTE* pSrcBuf = (FX_BYTE*)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(m_Face));
+ if (anti_alias != FXFT_RENDER_MODE_MONO && FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) == FXFT_PIXEL_MODE_MONO) {
+ int bytes = anti_alias == FXFT_RENDER_MODE_LCD ? 3 : 1;
+ for(int i = 0; i < bmheight; i++)
+ for(int n = 0; n < bmwidth; n++) {
+ FX_BYTE data = (pSrcBuf[i * src_pitch + n / 8] & (0x80 >> (n % 8))) ? 255 : 0;
+ for (int b = 0; b < bytes; b ++) {
+ pDestBuf[i * dest_pitch + n * bytes + b] = data;
+ }
+ }
+ } else {
+ FXSYS_memset32(pDestBuf, 0, dest_pitch * bmheight);
+ if (anti_alias == FXFT_RENDER_MODE_MONO && FXFT_Get_Bitmap_PixelMode(FXFT_Get_Glyph_Bitmap(m_Face)) == FXFT_PIXEL_MODE_MONO) {
+ int rowbytes = FXSYS_abs(src_pitch) > dest_pitch ? dest_pitch : FXSYS_abs(src_pitch);
+ for (int row = 0; row < bmheight; row ++) {
+ FXSYS_memcpy32(pDestBuf + row * dest_pitch, pSrcBuf + row * src_pitch, rowbytes);
+ }
+ } else {
+ _ContrastAdjust(pSrcBuf, pDestBuf, bmwidth, bmheight, src_pitch, dest_pitch);
+ _GammaAdjust(pDestBuf, bmwidth, bmheight, dest_pitch, CFX_GEModule::Get()->GetTextGammaTable());
+ }
+ }
+ FXFT_Set_Face_Internal_Flag(m_Face, transflag);
+ return pGlyphBitmap;
+}
+FX_BOOL _OutputGlyph(void* dib, int x, int y, CFX_Font* pFont,
+ int glyph_index, FX_ARGB argb)
+{
+ CFX_DIBitmap* pDib = (CFX_DIBitmap*)dib;
+ FXFT_Face face = pFont->GetFace();
+ int error = FXFT_Load_Glyph(face, glyph_index, FXFT_LOAD_NO_BITMAP);
+ if (error) {
+ return FALSE;
+ }
+ error = FXFT_Render_Glyph(face, FXFT_RENDER_MODE_NORMAL);
+ if (error) {
+ return FALSE;
+ }
+ int bmwidth = FXFT_Get_Bitmap_Width(FXFT_Get_Glyph_Bitmap(face));
+ int bmheight = FXFT_Get_Bitmap_Rows(FXFT_Get_Glyph_Bitmap(face));
+ int left = FXFT_Get_Glyph_BitmapLeft(face);
+ int top = FXFT_Get_Glyph_BitmapTop(face);
+ FX_LPCBYTE src_buf = (FX_LPCBYTE)FXFT_Get_Bitmap_Buffer(FXFT_Get_Glyph_Bitmap(face));
+ int src_pitch = FXFT_Get_Bitmap_Pitch(FXFT_Get_Glyph_Bitmap(face));
+ CFX_DIBitmap mask;
+ mask.Create(bmwidth, bmheight, FXDIB_8bppMask);
+ FX_LPBYTE dest_buf = mask.GetBuffer();
+ int dest_pitch = mask.GetPitch();
+ for (int row = 0; row < bmheight; row ++) {
+ FX_LPCBYTE src_scan = src_buf + row * src_pitch;
+ FX_LPBYTE dest_scan = dest_buf + row * dest_pitch;
+ FXSYS_memcpy32(dest_scan, src_scan, dest_pitch);
+ }
+ pDib->CompositeMask(x + left, y - top, bmwidth, bmheight, &mask, argb, 0, 0);
+ return TRUE;
+}
+FX_BOOL OutputText(void* dib, int x, int y, CFX_Font* pFont, double font_size,
+ CFX_AffineMatrix* pText_matrix, unsigned short const* text, unsigned long argb)
+{
+ if (!pFont) {
+ return FALSE;
+ }
+ FXFT_Face face = pFont->GetFace();
+ FXFT_Select_Charmap(pFont->m_Face, FXFT_ENCODING_UNICODE);
+ int transflag = FXFT_Get_Face_Internal_Flag(pFont->m_Face);
+ if (pText_matrix) {
+ FXFT_Matrix ft_matrix;
+ ft_matrix.xx = (signed long)(pText_matrix->a / 64 * 65536);
+ ft_matrix.xy = (signed long)(pText_matrix->c / 64 * 65536);
+ ft_matrix.yx = (signed long)(pText_matrix->b / 64 * 65536);
+ ft_matrix.yy = (signed long)(pText_matrix->d / 64 * 65536);
+ FXFT_Set_Transform(face, &ft_matrix, 0);
+ }
+ FX_FLOAT x_pos = 0;
+ for (; *text != 0; text ++) {
+ FX_WCHAR unicode = *text;
+ int glyph_index = FXFT_Get_Char_Index(pFont->m_Face, unicode);
+ if (glyph_index <= 0) {
+ continue;
+ }
+ int err = FXFT_Load_Glyph(pFont->m_Face, glyph_index, FXFT_LOAD_NO_SCALE | FXFT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH);
+ if (err) {
+ continue;
+ }
+ int w = FXFT_Get_Glyph_HoriAdvance(pFont->m_Face);
+ int em = FXFT_Get_Face_UnitsPerEM(pFont->m_Face);
+ FX_FLOAT x1, y1;
+ pText_matrix->Transform(x_pos, 0, x1, y1);
+ _OutputGlyph(dib, (int)x1 + x, (int) - y1 + y, pFont,
+ glyph_index, argb);
+ x_pos += (FX_FLOAT)w / em;
+ }
+ FXFT_Set_Face_Internal_Flag(pFont->m_Face, transflag);
+ return TRUE;
+}
+FX_BOOL OutputGlyph(void* dib, int x, int y, CFX_Font* pFont, double font_size,
+ CFX_AffineMatrix* pMatrix, unsigned long glyph_index, unsigned long argb)
+{
+ FXFT_Matrix ft_matrix;
+ if (pMatrix) {
+ ft_matrix.xx = (signed long)(pMatrix->a * font_size / 64 * 65536);
+ ft_matrix.xy = (signed long)(pMatrix->c * font_size / 64 * 65536);
+ ft_matrix.yx = (signed long)(pMatrix->b * font_size / 64 * 65536);
+ ft_matrix.yy = (signed long)(pMatrix->d * font_size / 64 * 65536);
+ } else {
+ ft_matrix.xx = (signed long)(font_size / 64 * 65536);
+ ft_matrix.xy = ft_matrix.yx = 0;
+ ft_matrix.yy = (signed long)(font_size / 64 * 65536);
+ }
+ int transflag = FXFT_Get_Face_Internal_Flag(pFont->m_Face);
+ FXFT_Set_Transform(pFont->m_Face, &ft_matrix, 0);
+ FX_BOOL ret = _OutputGlyph(dib, x, y, pFont,
+ glyph_index, argb);
+ FXFT_Set_Face_Internal_Flag(pFont->m_Face, transflag);
+ return ret;
+}
+const CFX_PathData* CFX_FaceCache::LoadGlyphPath(CFX_Font* pFont, FX_DWORD glyph_index, int dest_width)
+{
+ if (m_Face == NULL || glyph_index == (FX_DWORD) - 1) {
+ return NULL;
+ }
+ CFX_PathData* pGlyphPath = NULL;
+ FX_LPVOID key;
+ if (pFont->GetSubstFont())
+ key = (FX_LPVOID)(FX_UINTPTR)(glyph_index + ((pFont->GetSubstFont()->m_Weight / 16) << 15) +
+ ((pFont->GetSubstFont()->m_ItalicAngle / 2) << 21) + ((dest_width / 16) << 25) +
+ (pFont->IsVertical() << 31));
+ else {
+ key = (FX_LPVOID)(FX_UINTPTR)glyph_index;
+ }
+ if (m_PathMap.Lookup(key, (FX_LPVOID&)pGlyphPath)) {
+ return pGlyphPath;
+ }
+ pGlyphPath = pFont->LoadGlyphPath(glyph_index, dest_width);
+ m_PathMap.SetAt(key, pGlyphPath);
+ return pGlyphPath;
+}
+typedef struct {
+ FX_BOOL m_bCount;
+ int m_PointCount;
+ FX_PATHPOINT* m_pPoints;
+ int m_CurX;
+ int m_CurY;
+ FX_FLOAT m_CoordUnit;
+} OUTLINE_PARAMS;
+void _Outline_CheckEmptyContour(OUTLINE_PARAMS* param)
+{
+ if (param->m_PointCount >= 2 && param->m_pPoints[param->m_PointCount - 2].m_Flag == FXPT_MOVETO &&
+ param->m_pPoints[param->m_PointCount - 2].m_PointX == param->m_pPoints[param->m_PointCount - 1].m_PointX &&
+ param->m_pPoints[param->m_PointCount - 2].m_PointY == param->m_pPoints[param->m_PointCount - 1].m_PointY) {
+ param->m_PointCount -= 2;
+ }
+ if (param->m_PointCount >= 4 && param->m_pPoints[param->m_PointCount - 4].m_Flag == FXPT_MOVETO &&
+ param->m_pPoints[param->m_PointCount - 3].m_Flag == FXPT_BEZIERTO &&
+ param->m_pPoints[param->m_PointCount - 3].m_PointX == param->m_pPoints[param->m_PointCount - 4].m_PointX &&
+ param->m_pPoints[param->m_PointCount - 3].m_PointY == param->m_pPoints[param->m_PointCount - 4].m_PointY &&
+ param->m_pPoints[param->m_PointCount - 2].m_PointX == param->m_pPoints[param->m_PointCount - 4].m_PointX &&
+ param->m_pPoints[param->m_PointCount - 2].m_PointY == param->m_pPoints[param->m_PointCount - 4].m_PointY &&
+ param->m_pPoints[param->m_PointCount - 1].m_PointX == param->m_pPoints[param->m_PointCount - 4].m_PointX &&
+ param->m_pPoints[param->m_PointCount - 1].m_PointY == param->m_pPoints[param->m_PointCount - 4].m_PointY) {
+ param->m_PointCount -= 4;
+ }
+}
+extern "C" {
+ static int _Outline_MoveTo(const FXFT_Vector* to, void* user)
+ {
+ OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
+ if (!param->m_bCount) {
+ _Outline_CheckEmptyContour(param);
+ param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount].m_Flag = FXPT_MOVETO;
+ param->m_CurX = to->x;
+ param->m_CurY = to->y;
+ if (param->m_PointCount) {
+ param->m_pPoints[param->m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
+ }
+ }
+ param->m_PointCount ++;
+ return 0;
+ }
+};
+extern "C" {
+ static int _Outline_LineTo(const FXFT_Vector* to, void* user)
+ {
+ OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
+ if (!param->m_bCount) {
+ param->m_pPoints[param->m_PointCount].m_PointX = to->x / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount].m_PointY = to->y / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount].m_Flag = FXPT_LINETO;
+ param->m_CurX = to->x;
+ param->m_CurY = to->y;
+ }
+ param->m_PointCount ++;
+ return 0;
+ }
+};
+extern "C" {
+ static int _Outline_ConicTo(const FXFT_Vector* control, const FXFT_Vector* to, void* user)
+ {
+ OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
+ if (!param->m_bCount) {
+ param->m_pPoints[param->m_PointCount].m_PointX = (param->m_CurX + (control->x - param->m_CurX) * 2 / 3) / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount].m_PointY = (param->m_CurY + (control->y - param->m_CurY) * 2 / 3) / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO;
+ param->m_pPoints[param->m_PointCount + 1].m_PointX = (control->x + (to->x - control->x) / 3) / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount + 1].m_PointY = (control->y + (to->y - control->y) / 3) / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO;
+ param->m_pPoints[param->m_PointCount + 2].m_PointX = to->x / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount + 2].m_PointY = to->y / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO;
+ param->m_CurX = to->x;
+ param->m_CurY = to->y;
+ }
+ param->m_PointCount += 3;
+ return 0;
+ }
+};
+extern "C" {
+ static int _Outline_CubicTo(const FXFT_Vector* control1, const FXFT_Vector* control2, const FXFT_Vector* to, void* user)
+ {
+ OUTLINE_PARAMS* param = (OUTLINE_PARAMS*)user;
+ if (!param->m_bCount) {
+ param->m_pPoints[param->m_PointCount].m_PointX = control1->x / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount].m_PointY = control1->y / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount].m_Flag = FXPT_BEZIERTO;
+ param->m_pPoints[param->m_PointCount + 1].m_PointX = control2->x / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount + 1].m_PointY = control2->y / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount + 1].m_Flag = FXPT_BEZIERTO;
+ param->m_pPoints[param->m_PointCount + 2].m_PointX = to->x / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount + 2].m_PointY = to->y / param->m_CoordUnit;
+ param->m_pPoints[param->m_PointCount + 2].m_Flag = FXPT_BEZIERTO;
+ param->m_CurX = to->x;
+ param->m_CurY = to->y;
+ }
+ param->m_PointCount += 3;
+ return 0;
+ }
+};
+CFX_PathData* CFX_Font::LoadGlyphPath(FX_DWORD glyph_index, int dest_width)
+{
+ if (m_Face == NULL) {
+ return NULL;
+ }
+ FXFT_Set_Pixel_Sizes(m_Face, 0, 64);
+ FXFT_Matrix ft_matrix = {65536, 0, 0, 65536};
+ if (m_pSubstFont) {
+ if (m_pSubstFont->m_ItalicAngle) {
+ int skew = m_pSubstFont->m_ItalicAngle;
+ skew = skew <= -30 ? -58 : -g_AngleSkew[-skew];
+ if (m_bVertical) {
+ ft_matrix.yx += ft_matrix.yy * skew / 100;
+ } else {
+ ft_matrix.xy += -ft_matrix.xx * skew / 100;
+ }
+ }
+ if (m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) {
+ AdjustMMParams(glyph_index, dest_width, m_pSubstFont->m_Weight);
+ }
+ }
+ int transflag = FXFT_Get_Face_Internal_Flag(m_Face);
+ FXFT_Set_Transform(m_Face, &ft_matrix, 0);
+ int load_flags = (m_Face->face_flags & FT_FACE_FLAG_SFNT) ? FXFT_LOAD_NO_BITMAP : FXFT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING;
+ int error = FXFT_Load_Glyph(m_Face, glyph_index, load_flags);
+ if (error) {
+ FXFT_Set_Face_Internal_Flag(m_Face, transflag);
+ return NULL;
+ }
+ if (m_pSubstFont && !(m_pSubstFont->m_SubstFlags & FXFONT_SUBST_MM) && m_pSubstFont->m_Weight > 400) {
+ int level = 0;
+ if (m_pSubstFont->m_Charset == FXFONT_SHIFTJIS_CHARSET) {
+ level = g_WeightPow_SHIFTJIS[(m_pSubstFont->m_Weight - 400) / 10] * 2 * 65536 / 36655;
+ } else {
+ level = g_WeightPow[(m_pSubstFont->m_Weight - 400) / 10] * 2;
+ }
+ FXFT_Outline_Embolden(FXFT_Get_Glyph_Outline(m_Face), level);
+ }
+ FXFT_Outline_Funcs funcs;
+ funcs.move_to = _Outline_MoveTo;
+ funcs.line_to = _Outline_LineTo;
+ funcs.conic_to = _Outline_ConicTo;
+ funcs.cubic_to = _Outline_CubicTo;
+ funcs.shift = 0;
+ funcs.delta = 0;
+ OUTLINE_PARAMS params;
+ params.m_bCount = TRUE;
+ params.m_PointCount = 0;
+ FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
+ if (params.m_PointCount == 0) {
+ FXFT_Set_Face_Internal_Flag(m_Face, transflag);
+ return NULL;
+ }
+ CFX_PathData* pPath = FX_NEW CFX_PathData;
+ if (!pPath) {
+ return NULL;
+ }
+ pPath->SetPointCount(params.m_PointCount);
+ params.m_bCount = FALSE;
+ params.m_PointCount = 0;
+ params.m_pPoints = pPath->GetPoints();
+ params.m_CurX = params.m_CurY = 0;
+ params.m_CoordUnit = 64 * 64.0;
+ FXFT_Outline_Decompose(FXFT_Get_Glyph_Outline(m_Face), &funcs, &params);
+ _Outline_CheckEmptyContour(&params);
+ pPath->TrimPoints(params.m_PointCount);
+ if (params.m_PointCount) {
+ pPath->GetPoints()[params.m_PointCount - 1].m_Flag |= FXPT_CLOSEFIGURE;
+ }
+ FXFT_Set_Face_Internal_Flag(m_Face, transflag);
+ return pPath;
+}
+void _CFX_UniqueKeyGen::Generate(int count, ...)
+{
+ va_list argList;
+ va_start(argList, count);
+ for (int i = 0; i < count; i ++) {
+ int p = va_arg(argList, int);
+ ((FX_DWORD*)m_Key)[i] = p;
+ }
+ va_end(argList);
+ m_KeyLen = count * sizeof(FX_DWORD);
+}
diff --git a/core/src/fxge/ge/text_int.h b/core/src/fxge/ge/text_int.h
index 7608f8a2ed..a3c9417bfc 100644
--- a/core/src/fxge/ge/text_int.h
+++ b/core/src/fxge/ge/text_int.h
@@ -1,100 +1,100 @@
-// 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
-
-struct _CFX_UniqueKeyGen {
- void Generate(int count, ...);
- FX_CHAR m_Key[128];
- int m_KeyLen;
-};
-class CFX_SizeGlyphCache : public CFX_Object
-{
-public:
- CFX_SizeGlyphCache()
- {
- m_GlyphMap.InitHashTable(253);
- }
- ~CFX_SizeGlyphCache();
- CFX_MapPtrToPtr m_GlyphMap;
-};
-class CTTFontDesc : public CFX_Object
-{
-public:
- CTTFontDesc()
- {
- m_Type = 0;
- m_pFontData = NULL;
- m_RefCount = 0;
- }
- ~CTTFontDesc();
- FX_BOOL ReleaseFace(FXFT_Face face);
- int m_Type;
- union {
- struct {
- FX_BOOL m_bItalic;
- FX_BOOL m_bBold;
- FXFT_Face m_pFace;
- } m_SingleFace;
- struct {
- FXFT_Face m_pFaces[16];
- } m_TTCFace;
- };
- FX_BYTE* m_pFontData;
- int m_RefCount;
-};
-class CFX_UnicodeEncoding : public IFX_FontEncoding
-{
-public:
- CFX_UnicodeEncoding(CFX_Font* pFont);
- virtual FX_DWORD GlyphFromCharCodeEx(FX_DWORD charcode, int encoding = ENCODING_UNICODE);
-private:
- CFX_Font* m_pFont;
- virtual FX_DWORD GlyphFromCharCode(FX_DWORD charcode);
- virtual CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const
- {
- return CFX_WideString((FX_WCHAR)charcode);
- }
- virtual FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const
- {
- return Unicode;
- }
- virtual FX_BOOL IsUnicodeCompatible() const
- {
- return TRUE;
- }
-};
-#define CHARSET_FLAG_ANSI 1
-#define CHARSET_FLAG_SYMBOL 2
-#define CHARSET_FLAG_SHIFTJIS 4
-#define CHARSET_FLAG_BIG5 8
-#define CHARSET_FLAG_GB 16
-#define CHARSET_FLAG_KOREAN 32
-class CFontFaceInfo : public CFX_Object
-{
-public:
- CFX_ByteString m_FilePath;
- CFX_ByteString m_FaceName;
- FX_DWORD m_Styles;
- FX_DWORD m_Charsets;
- FX_DWORD m_FontOffset;
- FX_DWORD m_FileSize;
- CFX_ByteString m_FontTables;
-};
-class CFontFileFaceInfo : public CFX_Object
-{
-public:
- CFontFileFaceInfo();
- ~CFontFileFaceInfo();
- IFX_FileStream* m_pFile;
- FXFT_Face m_Face;
- CFX_ByteString m_FaceName;
- FX_DWORD m_Charsets;
- FX_DWORD m_FileSize;
- FX_DWORD m_FontOffset;
- int m_Weight;
- FX_BOOL m_bItalic;
- int m_PitchFamily;
- CFX_ByteString m_FontTables;
-};
+// 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
+
+struct _CFX_UniqueKeyGen {
+ void Generate(int count, ...);
+ FX_CHAR m_Key[128];
+ int m_KeyLen;
+};
+class CFX_SizeGlyphCache : public CFX_Object
+{
+public:
+ CFX_SizeGlyphCache()
+ {
+ m_GlyphMap.InitHashTable(253);
+ }
+ ~CFX_SizeGlyphCache();
+ CFX_MapPtrToPtr m_GlyphMap;
+};
+class CTTFontDesc : public CFX_Object
+{
+public:
+ CTTFontDesc()
+ {
+ m_Type = 0;
+ m_pFontData = NULL;
+ m_RefCount = 0;
+ }
+ ~CTTFontDesc();
+ FX_BOOL ReleaseFace(FXFT_Face face);
+ int m_Type;
+ union {
+ struct {
+ FX_BOOL m_bItalic;
+ FX_BOOL m_bBold;
+ FXFT_Face m_pFace;
+ } m_SingleFace;
+ struct {
+ FXFT_Face m_pFaces[16];
+ } m_TTCFace;
+ };
+ FX_BYTE* m_pFontData;
+ int m_RefCount;
+};
+class CFX_UnicodeEncoding : public IFX_FontEncoding
+{
+public:
+ CFX_UnicodeEncoding(CFX_Font* pFont);
+ virtual FX_DWORD GlyphFromCharCodeEx(FX_DWORD charcode, int encoding = ENCODING_UNICODE);
+private:
+ CFX_Font* m_pFont;
+ virtual FX_DWORD GlyphFromCharCode(FX_DWORD charcode);
+ virtual CFX_WideString UnicodeFromCharCode(FX_DWORD charcode) const
+ {
+ return CFX_WideString((FX_WCHAR)charcode);
+ }
+ virtual FX_DWORD CharCodeFromUnicode(FX_WCHAR Unicode) const
+ {
+ return Unicode;
+ }
+ virtual FX_BOOL IsUnicodeCompatible() const
+ {
+ return TRUE;
+ }
+};
+#define CHARSET_FLAG_ANSI 1
+#define CHARSET_FLAG_SYMBOL 2
+#define CHARSET_FLAG_SHIFTJIS 4
+#define CHARSET_FLAG_BIG5 8
+#define CHARSET_FLAG_GB 16
+#define CHARSET_FLAG_KOREAN 32
+class CFontFaceInfo : public CFX_Object
+{
+public:
+ CFX_ByteString m_FilePath;
+ CFX_ByteString m_FaceName;
+ FX_DWORD m_Styles;
+ FX_DWORD m_Charsets;
+ FX_DWORD m_FontOffset;
+ FX_DWORD m_FileSize;
+ CFX_ByteString m_FontTables;
+};
+class CFontFileFaceInfo : public CFX_Object
+{
+public:
+ CFontFileFaceInfo();
+ ~CFontFileFaceInfo();
+ IFX_FileStream* m_pFile;
+ FXFT_Face m_Face;
+ CFX_ByteString m_FaceName;
+ FX_DWORD m_Charsets;
+ FX_DWORD m_FileSize;
+ FX_DWORD m_FontOffset;
+ int m_Weight;
+ FX_BOOL m_bItalic;
+ int m_PitchFamily;
+ CFX_ByteString m_FontTables;
+};
diff --git a/core/src/fxge/win32/dwrite_int.h b/core/src/fxge/win32/dwrite_int.h
index 1f0770d0bf..2eecc7c76b 100644
--- a/core/src/fxge/win32/dwrite_int.h
+++ b/core/src/fxge/win32/dwrite_int.h
@@ -1,59 +1,59 @@
-// 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 _FX_DIRECT_WRITE_
-#define _FX_DIRECT_WRITE_
-#ifndef DECLSPEC_UUID
-#if (_MSC_VER >= 1100) && defined (__cplusplus)
-#define DECLSPEC_UUID(x) __declspec(uuid(x))
-#else
-#define DECLSPEC_UUID(x)
-#endif
-#endif
-#ifndef DECLSPEC_NOVTABLE
-#if (_MSC_VER >= 1100) && defined(__cplusplus)
-#define DECLSPEC_NOVTABLE __declspec(novtable)
-#else
-#define DECLSPEC_NOVTABLE
-#endif
-#endif
-#if(WINVER < 0x0500)
-#ifndef _MAC
-DECLARE_HANDLE(HMONITOR);
-#endif
-#endif
-class CDWriteExt
-{
-public:
- CDWriteExt();
- ~CDWriteExt();
-
- void Load();
- void Unload();
-
- FX_BOOL IsAvailable()
- {
- return m_pDWriteFactory != NULL;
- }
-
- void* DwCreateFontFaceFromStream(FX_LPBYTE pData, FX_DWORD size, int simulation_style);
- FX_BOOL DwCreateRenderingTarget(CFX_DIBitmap* pSrc, void** renderTarget);
- void DwDeleteRenderingTarget(void* renderTarget);
- FX_BOOL DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix,
- void *font, FX_FLOAT font_size, FX_ARGB text_color,
- int glyph_count, unsigned short* glyph_indices,
- FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY,
- void* glyph_offsets,
- FX_FLOAT* glyph_advances);
- void DwDeleteFont(void* pFont);
-
-protected:
- void* m_hModule;
- void* m_pDWriteFactory;
- void* m_pDwFontContext;
- void* m_pDwTextRenderer;
-};
-#endif
+// 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 _FX_DIRECT_WRITE_
+#define _FX_DIRECT_WRITE_
+#ifndef DECLSPEC_UUID
+#if (_MSC_VER >= 1100) && defined (__cplusplus)
+#define DECLSPEC_UUID(x) __declspec(uuid(x))
+#else
+#define DECLSPEC_UUID(x)
+#endif
+#endif
+#ifndef DECLSPEC_NOVTABLE
+#if (_MSC_VER >= 1100) && defined(__cplusplus)
+#define DECLSPEC_NOVTABLE __declspec(novtable)
+#else
+#define DECLSPEC_NOVTABLE
+#endif
+#endif
+#if(WINVER < 0x0500)
+#ifndef _MAC
+DECLARE_HANDLE(HMONITOR);
+#endif
+#endif
+class CDWriteExt
+{
+public:
+ CDWriteExt();
+ ~CDWriteExt();
+
+ void Load();
+ void Unload();
+
+ FX_BOOL IsAvailable()
+ {
+ return m_pDWriteFactory != NULL;
+ }
+
+ void* DwCreateFontFaceFromStream(FX_LPBYTE pData, FX_DWORD size, int simulation_style);
+ FX_BOOL DwCreateRenderingTarget(CFX_DIBitmap* pSrc, void** renderTarget);
+ void DwDeleteRenderingTarget(void* renderTarget);
+ FX_BOOL DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix,
+ void *font, FX_FLOAT font_size, FX_ARGB text_color,
+ int glyph_count, unsigned short* glyph_indices,
+ FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY,
+ void* glyph_offsets,
+ FX_FLOAT* glyph_advances);
+ void DwDeleteFont(void* pFont);
+
+protected:
+ void* m_hModule;
+ void* m_pDWriteFactory;
+ void* m_pDwFontContext;
+ void* m_pDwTextRenderer;
+};
+#endif
diff --git a/core/src/fxge/win32/fx_win32_device.cpp b/core/src/fxge/win32/fx_win32_device.cpp
index e3f5ae0609..592886249b 100644
--- a/core/src/fxge/win32/fx_win32_device.cpp
+++ b/core/src/fxge/win32/fx_win32_device.cpp
@@ -1,1200 +1,1200 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include "../../../include/fxge/fx_ge_win32.h"
-#include <crtdbg.h>
-#include "../agg/include/fxfx_agg_clip_liang_barsky.h"
-#include "dwrite_int.h"
-#include "win32_int.h"
-#include "../ge/text_int.h"
-#include "../dib/dib_int.h"
-#include "../agg/include/fx_agg_driver.h"
-#include "../../../include/fxge/fx_freetype.h"
-#include "../../../include/fxcodec/fx_codec.h"
-class CWin32FontInfo : public IFX_SystemFontInfo
-{
-public:
- CWin32FontInfo();
- ~CWin32FontInfo();
- virtual void Release();
- virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper);
- virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR face, FX_BOOL& bExact);
- virtual void* GetFont(FX_LPCSTR face)
- {
- return NULL;
- }
- virtual FX_DWORD GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size);
- virtual void DeleteFont(void* hFont);
- virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name);
- virtual FX_BOOL GetFontCharset(void* hFont, int& charset);
- FX_BOOL IsOpenTypeFromDiv(const LOGFONTA *plf);
- FX_BOOL IsSupportFontFormDiv(const LOGFONTA* plf);
- void AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType);
- void GetGBPreference(CFX_ByteString& face, int weight, int picth_family);
- void GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family);
- CFX_ByteString FindFont(const CFX_ByteString& name);
- HDC m_hDC;
- CFX_FontMapper* m_pMapper;
- CFX_ByteString m_LastFamily;
- CFX_ByteString m_KaiTi, m_FangSong;
-};
-CWin32FontInfo::CWin32FontInfo()
-{
- m_hDC = CreateCompatibleDC(NULL);
-}
-CWin32FontInfo::~CWin32FontInfo()
-{
- m_pMapper = NULL;
-}
-void CWin32FontInfo::Release()
-{
- DeleteDC(m_hDC);
- delete this;
-}
-#define TT_MAKE_TAG(x1, x2, x3, x4) (((FX_DWORD)x1<<24)|((FX_DWORD)x2<<16)|((FX_DWORD)x3<<8)|(FX_DWORD)x4)
-FX_BOOL CWin32FontInfo::IsOpenTypeFromDiv(const LOGFONTA *plf)
-{
- HFONT hFont = CreateFontIndirectA(plf);
- FX_BOOL ret = FALSE;
- FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
- if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
- FX_DWORD lVersion = 0;
- GetFontData(hFont, 0, (FX_BYTE*)(&lVersion), sizeof(FX_DWORD));
- lVersion = (((FX_DWORD)(FX_BYTE)(lVersion)) << 24) | ((FX_DWORD)((FX_BYTE)(lVersion >> 8))) << 16 |
- ((FX_DWORD)((FX_BYTE)(lVersion >> 16))) << 8 | ((FX_BYTE)(lVersion >> 24));
- if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
- lVersion == 0x00010000 ||
- lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
- lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
- lVersion == 0x00020000) {
- ret = TRUE;
- }
- }
- DeleteFont(hFont);
- return ret;
-}
-FX_BOOL CWin32FontInfo::IsSupportFontFormDiv(const LOGFONTA* plf)
-{
- HFONT hFont = CreateFontIndirectA(plf);
- FX_BOOL ret = FALSE;
- FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
- if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
- FX_DWORD lVersion = 0;
- GetFontData(hFont, 0, (FX_BYTE*)(&lVersion), sizeof(FX_DWORD));
- lVersion = (((FX_DWORD)(FX_BYTE)(lVersion)) << 24) | ((FX_DWORD)((FX_BYTE)(lVersion >> 8))) << 16 |
- ((FX_DWORD)((FX_BYTE)(lVersion >> 16))) << 8 | ((FX_BYTE)(lVersion >> 24));
- if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
- lVersion == 0x00010000 ||
- lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
- lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
- lVersion == 0x00020000) {
- ret = TRUE;
- } else if ((lVersion & 0xFFFF0000) == TT_MAKE_TAG(0x80, 0x01, 0x00, 0x00) ||
- (lVersion & 0xFFFF0000) == TT_MAKE_TAG('%', '!', 0, 0)) {
- ret = TRUE;
- }
- }
- DeleteFont(hFont);
- return ret;
-}
-void CWin32FontInfo::AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType)
-{
- CFX_ByteString name(plf->lfFaceName, -1);
- if (name[0] == '@') {
- return;
- }
- if (name == m_LastFamily) {
- m_pMapper->AddInstalledFont(name, plf->lfCharSet);
- return;
- }
- if (!(FontType & TRUETYPE_FONTTYPE) && !(FontType & DEVICE_FONTTYPE)) {
- return;
- }
- if (!(FontType & TRUETYPE_FONTTYPE)) {
- if (!IsSupportFontFormDiv(plf)) {
- return;
- }
- }
- m_pMapper->AddInstalledFont(name, plf->lfCharSet);
- m_LastFamily = name;
-}
-static int CALLBACK FontEnumProc(
- const LOGFONTA *plf,
- const TEXTMETRICA *lpntme,
- FX_DWORD FontType,
- LPARAM lParam
-)
-{
- CWin32FontInfo* pFontInfo = (CWin32FontInfo*)lParam;
- if (pFontInfo->m_pMapper->GetFontEnumerator()) {
- pFontInfo->m_pMapper->GetFontEnumerator()->HitFont();
- }
- pFontInfo->AddInstalledFont(plf, FontType);
- return 1;
-}
-FX_BOOL CWin32FontInfo::EnumFontList(CFX_FontMapper* pMapper)
-{
- m_pMapper = pMapper;
- LOGFONTA lf;
- FXSYS_memset32(&lf, 0, sizeof(LOGFONTA));
- lf.lfCharSet = DEFAULT_CHARSET;
- lf.lfFaceName[0] = 0;
- lf.lfPitchAndFamily = 0;
- EnumFontFamiliesExA(m_hDC, &lf, (FONTENUMPROCA)FontEnumProc, (FX_UINTPTR)this, 0);
- if (pMapper->GetFontEnumerator()) {
- pMapper->GetFontEnumerator()->Finish();
- }
- return TRUE;
-}
-static const struct {
- FX_LPCSTR m_pFaceName;
- FX_LPCSTR m_pVariantName;
-}
-VariantNames[] = {
- {"DFKai-SB", "\x19\x6A\x77\x69\xD4\x9A"},
-};
-static const struct {
- FX_LPCSTR m_pName;
- FX_LPCSTR m_pWinName;
- FX_BOOL m_bBold;
- FX_BOOL m_bItalic;
-}
-Base14Substs[] = {
- {"Courier", "Courier New", FALSE, FALSE},
- {"Courier-Bold", "Courier New", TRUE, FALSE},
- {"Courier-BoldOblique", "Courier New", TRUE, TRUE},
- {"Courier-Oblique", "Courier New", FALSE, TRUE},
- {"Helvetica", "Arial", FALSE, FALSE},
- {"Helvetica-Bold", "Arial", TRUE, FALSE},
- {"Helvetica-BoldOblique", "Arial", TRUE, TRUE},
- {"Helvetica-Oblique", "Arial", FALSE, TRUE},
- {"Times-Roman", "Times New Roman", FALSE, FALSE},
- {"Times-Bold", "Times New Roman", TRUE, FALSE},
- {"Times-BoldItalic", "Times New Roman", TRUE, TRUE},
- {"Times-Italic", "Times New Roman", FALSE, TRUE},
-};
-CFX_ByteString CWin32FontInfo::FindFont(const CFX_ByteString& name)
-{
- if (m_pMapper == NULL) {
- return name;
- }
- int nFonts = m_pMapper->m_InstalledTTFonts.GetSize();
- for (int i = 0; i < nFonts; i ++) {
- CFX_ByteString thisname = m_pMapper->m_InstalledTTFonts[i];
- if (thisname[0] == ' ') {
- if (thisname.Mid(1, name.GetLength()) == name) {
- return m_pMapper->m_InstalledTTFonts[i + 1];
- }
- } else if (thisname.Left(name.GetLength()) == name) {
- return m_pMapper->m_InstalledTTFonts[i];
- }
- }
- return CFX_ByteString();
-}
-struct _FontNameMap {
- FX_LPCSTR m_pSubFontName;
- FX_LPCSTR m_pSrcFontName;
-};
-const _FontNameMap g_JpFontNameMap[] = {
- {"MS Mincho", "Heiseimin-W3"},
- {"MS Gothic", "Jun101-Light"},
-};
-const _FontNameMap g_GbFontNameMap[1];
-extern "C" {
- static int compareString(const void* key, const void* element)
- {
- return FXSYS_stricmp((FX_LPCSTR)key, ((_FontNameMap*)element)->m_pSrcFontName);
- }
-}
-FX_BOOL _GetSubFontName(CFX_ByteString& name, int lang)
-{
- int size = sizeof g_JpFontNameMap;
- void* pFontnameMap = (void*)g_JpFontNameMap;
- if (lang == 1) {
- size = sizeof g_GbFontNameMap;
- pFontnameMap = (void*)g_GbFontNameMap;
- } else if (lang == 2) {
- size = 0;
- }
- _FontNameMap* found = (_FontNameMap*)FXSYS_bsearch((FX_LPCSTR)name, pFontnameMap,
- size / sizeof (_FontNameMap), sizeof (_FontNameMap), compareString);
- if (found == NULL) {
- return FALSE;
- }
- name = found->m_pSubFontName;
- return TRUE;
-}
-void CWin32FontInfo::GetGBPreference(CFX_ByteString& face, int weight, int picth_family)
-{
- if (face.Find("KaiTi") >= 0 || face.Find("\xbf\xac") >= 0) {
- if (m_KaiTi.IsEmpty()) {
- m_KaiTi = FindFont("KaiTi");
- if (m_KaiTi.IsEmpty()) {
- m_KaiTi = "SimSun";
- }
- }
- face = m_KaiTi;
- } else if (face.Find("FangSong") >= 0 || face.Find("\xb7\xc2\xcb\xce") >= 0) {
- if (m_FangSong.IsEmpty()) {
- m_FangSong = FindFont("FangSong");
- if (m_FangSong.IsEmpty()) {
- m_FangSong = "SimSun";
- }
- }
- face = m_FangSong;
- } else if (face.Find("SimSun") >= 0 || face.Find("\xcb\xce") >= 0) {
- face = "SimSun";
- } else if (face.Find("SimHei") >= 0 || face.Find("\xba\xda") >= 0) {
- face = "SimHei";
- } else if (!(picth_family & FF_ROMAN) && weight > 550) {
- face = "SimHei";
- } else {
- face = "SimSun";
- }
-}
-void CWin32FontInfo::GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family)
-{
- if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
- if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
- face = "MS PGothic";
- } else if (face.Find("UI Gothic") >= 0) {
- face = "MS UI Gothic";
- } else {
- if (face.Find("HGSGothicM") >= 0 || face.Find("HGMaruGothicMPRO") >= 0) {
- face = "MS PGothic";
- } else {
- face = "MS Gothic";
- }
- }
- return;
- } else if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
- if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) {
- face = "MS PMincho";
- } else {
- face = "MS Mincho";
- }
- return;
- }
- if (_GetSubFontName(face, 0)) {
- return;
- }
- if (!(picth_family & FF_ROMAN) && weight > 400) {
- face = "MS PGothic";
- } else {
- face = "MS PMincho";
- }
-}
-void* CWin32FontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact)
-{
- CFX_ByteString face = cstr_face;
- int iBaseFont;
- for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++)
- if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) {
- face = Base14Substs[iBaseFont].m_pWinName;
- weight = Base14Substs[iBaseFont].m_bBold ? FW_BOLD : FW_NORMAL;
- bItalic = Base14Substs[iBaseFont].m_bItalic;
- bExact = TRUE;
- break;
- }
- if (charset == ANSI_CHARSET || charset == SYMBOL_CHARSET) {
- charset = DEFAULT_CHARSET;
- }
- int subst_pitch_family = pitch_family;
- switch (charset) {
- case SHIFTJIS_CHARSET:
- subst_pitch_family = FF_ROMAN;
- break;
- case CHINESEBIG5_CHARSET:
- case HANGUL_CHARSET:
- case GB2312_CHARSET:
- subst_pitch_family = 0;
- break;
- }
- HFONT hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
- 0, 0, subst_pitch_family, face);
- char facebuf[100];
- HFONT hOldFont = (HFONT)::SelectObject(m_hDC, hFont);
- int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
- ::SelectObject(m_hDC, hOldFont);
- if (face.EqualNoCase(facebuf)) {
- return hFont;
- }
- int iCount = sizeof(VariantNames) / sizeof(VariantNames[0]);
- for (int i = 0; i < iCount; ++i) {
- if (face == VariantNames[i].m_pFaceName) {
- CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf);
- CFX_WideString wsName = CFX_WideString::FromUTF16LE((const unsigned short*)VariantNames[i].m_pVariantName);
- if (wsFace == wsName) {
- return hFont;
- }
- }
- }
- ::DeleteObject(hFont);
- if (charset == DEFAULT_CHARSET) {
- return NULL;
- }
- switch (charset) {
- case SHIFTJIS_CHARSET:
- GetJapanesePreference(face, weight, pitch_family);
- break;
- case GB2312_CHARSET:
- GetGBPreference(face, weight, pitch_family);
- break;
- case HANGUL_CHARSET:
- face = "Gulim";
- break;
- case CHINESEBIG5_CHARSET:
- if (face.Find("MSung") >= 0) {
- face = "MingLiU";
- } else {
- face = "PMingLiU";
- }
- break;
- }
- hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
- 0, 0, subst_pitch_family, face);
- return hFont;
-}
-void CWin32FontInfo::DeleteFont(void* hFont)
-{
- ::DeleteObject(hFont);
-}
-FX_DWORD CWin32FontInfo::GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size)
-{
- HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
- table = FXDWORD_FROM_MSBFIRST(table);
- size = ::GetFontData(m_hDC, table, 0, buffer, size);
- ::SelectObject(m_hDC, hOldFont);
- if (size == GDI_ERROR) {
- return 0;
- }
- return size;
-}
-FX_BOOL CWin32FontInfo::GetFaceName(void* hFont, CFX_ByteString& name)
-{
- char facebuf[100];
- HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
- int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
- ::SelectObject(m_hDC, hOldFont);
- if (ret == 0) {
- return FALSE;
- }
- name = facebuf;
- return TRUE;
-}
-FX_BOOL CWin32FontInfo::GetFontCharset(void* hFont, int& charset)
-{
- TEXTMETRIC tm;
- HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
- ::GetTextMetrics(m_hDC, &tm);
- ::SelectObject(m_hDC, hOldFont);
- charset = tm.tmCharSet;
- return TRUE;
-}
-#ifndef _FPDFAPI_MINI_
-IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
-{
- return FX_NEW CWin32FontInfo;
-}
-#endif
-void CFX_GEModule::InitPlatform()
-{
- CWin32Platform* pPlatformData = FX_NEW CWin32Platform;
- if (!pPlatformData) {
- return;
- }
- OSVERSIONINFO ver;
- ver.dwOSVersionInfoSize = sizeof(ver);
- GetVersionEx(&ver);
- pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5;
- pPlatformData->m_GdiplusExt.Load();
- m_pPlatformData = pPlatformData;
- m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
-}
-void CFX_GEModule::DestroyPlatform()
-{
- if (m_pPlatformData) {
- delete (CWin32Platform*)m_pPlatformData;
- }
- m_pPlatformData = NULL;
-}
-CGdiDeviceDriver::CGdiDeviceDriver(HDC hDC, int device_class)
-{
- m_hDC = hDC;
- m_DeviceClass = device_class;
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- SetStretchBltMode(hDC, pPlatform->m_bHalfTone ? HALFTONE : COLORONCOLOR);
- if (GetObjectType(m_hDC) == OBJ_MEMDC) {
- HBITMAP hBitmap = CreateBitmap(1, 1, 1, 1, NULL);
- hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap);
- BITMAP bitmap;
- GetObject(hBitmap, sizeof bitmap, &bitmap);
- m_nBitsPerPixel = bitmap.bmBitsPixel;
- m_Width = bitmap.bmWidth;
- m_Height = abs(bitmap.bmHeight);
- hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap);
- DeleteObject(hBitmap);
- } else {
- m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL);
- m_Width = ::GetDeviceCaps(m_hDC, HORZRES);
- m_Height = ::GetDeviceCaps(m_hDC, VERTRES);
- }
- if (m_DeviceClass != FXDC_DISPLAY) {
- m_RenderCaps = FXRC_BIT_MASK;
- } else {
- m_RenderCaps = FXRC_GET_BITS | FXRC_BIT_MASK;
- }
-}
-int CGdiDeviceDriver::GetDeviceCaps(int caps_id)
-{
- switch (caps_id) {
- case FXDC_DEVICE_CLASS:
- return m_DeviceClass;
- case FXDC_PIXEL_WIDTH:
- return m_Width;
- case FXDC_PIXEL_HEIGHT:
- return m_Height;
- case FXDC_BITS_PIXEL:
- return m_nBitsPerPixel;
- case FXDC_RENDER_CAPS:
- return m_RenderCaps;
- }
- return 0;
-}
-FX_LPVOID CGdiDeviceDriver::GetClipRgn()
-{
- HRGN hClipRgn = CreateRectRgn(0, 0, 1, 1);
- if (::GetClipRgn(m_hDC, hClipRgn) == 0) {
- DeleteObject(hClipRgn);
- hClipRgn = NULL;
- }
- return (FX_LPVOID)hClipRgn;
-}
-FX_BOOL CGdiDeviceDriver::GDI_SetDIBits(const CFX_DIBitmap* pBitmap1, const FX_RECT* pSrcRect, int left, int top, void* pIccTransform)
-{
- if (m_DeviceClass == FXDC_PRINTER) {
- CFX_DIBitmap* pBitmap = pBitmap1->FlipImage(FALSE, TRUE);
- if (pBitmap == NULL) {
- return FALSE;
- }
- if ((pBitmap->IsCmykImage() || pIccTransform) &&
- !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
- return FALSE;
- }
- int width = pSrcRect->Width(), height = pSrcRect->Height();
- int pitch = pBitmap->GetPitch();
- LPBYTE pBuffer = pBitmap->GetBuffer();
- CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
- ((BITMAPINFOHEADER*)(FX_LPCSTR)info)->biHeight *= -1;
- FX_RECT dst_rect(0, 0, width, height);
- dst_rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
- int dst_width = dst_rect.Width();
- int dst_height = dst_rect.Height();
- ::StretchDIBits(m_hDC, left, top, dst_width, dst_height,
- 0, 0, dst_width, dst_height, pBuffer, (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS, SRCCOPY);
- delete pBitmap;
- } else {
- CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
- if ((pBitmap->IsCmykImage() || pIccTransform) &&
- (pBitmap = pBitmap->CloneConvert(FXDIB_Rgb, NULL, pIccTransform)) == NULL) {
- return FALSE;
- }
- int width = pSrcRect->Width(), height = pSrcRect->Height();
- int pitch = pBitmap->GetPitch();
- LPBYTE pBuffer = pBitmap->GetBuffer();
- CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
- ::SetDIBitsToDevice(m_hDC, left, top, width, height, pSrcRect->left, pBitmap->GetHeight() - pSrcRect->bottom,
- 0, pBitmap->GetHeight(), pBuffer, (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
- if (pBitmap != pBitmap1) {
- delete pBitmap;
- }
- }
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::GDI_StretchDIBits(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD flags, void* pIccTransform)
-{
- CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
- if (pBitmap == NULL) {
- return FALSE;
- }
- if ((pBitmap->IsCmykImage() || pIccTransform) &&
- !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
- return FALSE;
- }
- CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
- if (abs(dest_width) * abs(dest_height) < pBitmap1->GetWidth() * pBitmap1->GetHeight() * 4 ||
- (flags & FXDIB_INTERPOL) || (flags & FXDIB_BICUBIC_INTERPOL)) {
- SetStretchBltMode(m_hDC, HALFTONE);
- } else {
- SetStretchBltMode(m_hDC, COLORONCOLOR);
- }
- CFX_DIBitmap* pToStrechBitmap = pBitmap;
- bool del = false;
- if (m_DeviceClass == FXDC_PRINTER && (pBitmap->GetWidth() * pBitmap->GetHeight() > abs(dest_width) * abs(dest_height))) {
- pToStrechBitmap = pBitmap->StretchTo(dest_width, dest_height);
- del = true;
- }
- CFX_ByteString toStrechBitmapInfo = CFX_WindowsDIB::GetBitmapInfo(pToStrechBitmap);
- ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
- 0, 0, pToStrechBitmap->GetWidth(), pToStrechBitmap->GetHeight(), pToStrechBitmap->GetBuffer(),
- (BITMAPINFO*)(FX_LPCSTR)toStrechBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
- if (del) {
- delete pToStrechBitmap;
- }
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
- int alpha_flag, void* pIccTransform)
-{
- CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
- if (pBitmap == NULL) {
- return FALSE;
- }
- _Color2Argb(bitmap_color, bitmap_color, alpha_flag | (1 << 24), pIccTransform);
- int width = pBitmap->GetWidth(), height = pBitmap->GetHeight();
- struct {
- BITMAPINFOHEADER bmiHeader;
- FX_DWORD bmiColors[2];
- } bmi;
- FXSYS_memset32(&bmi.bmiHeader, 0, sizeof (BITMAPINFOHEADER));
- bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmi.bmiHeader.biBitCount = 1;
- bmi.bmiHeader.biCompression = BI_RGB;
- bmi.bmiHeader.biHeight = -height;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biWidth = width;
- if (m_nBitsPerPixel != 1) {
- SetStretchBltMode(m_hDC, HALFTONE);
- }
- bmi.bmiColors[0] = 0xffffff;
- bmi.bmiColors[1] = 0;
- ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
- 0, 0, width, height, pBitmap->GetBuffer(), (BITMAPINFO*)&bmi, DIB_RGB_COLORS, SRCAND);
- return TRUE;
-}
-BOOL CGdiDeviceDriver::GetClipBox(FX_RECT* pRect)
-{
- return ::GetClipBox(m_hDC, (RECT*)pRect);
-}
-FX_BOOL CGdiDeviceDriver::SetClipRgn(FX_LPVOID hRgn)
-{
- ::SelectClipRgn(m_hDC, (HRGN)hRgn);
- return TRUE;
-}
-static HPEN _CreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, FX_DWORD argb)
-{
- FX_FLOAT width;
- FX_FLOAT scale = 1.f;
- if (pMatrix)
- scale = FXSYS_fabs(pMatrix->a) > FXSYS_fabs(pMatrix->b) ?
- FXSYS_fabs(pMatrix->a) : FXSYS_fabs(pMatrix->b);
- if (pGraphState) {
- width = scale * pGraphState->m_LineWidth;
- } else {
- width = 1.0f;
- }
- FX_DWORD PenStyle = PS_GEOMETRIC;
- if (width < 1) {
- width = 1;
- }
- if(pGraphState->m_DashCount) {
- PenStyle |= PS_USERSTYLE;
- } else {
- PenStyle |= PS_SOLID;
- }
- switch(pGraphState->m_LineCap) {
- case 0:
- PenStyle |= PS_ENDCAP_FLAT;
- break;
- case 1:
- PenStyle |= PS_ENDCAP_ROUND;
- break;
- case 2:
- PenStyle |= PS_ENDCAP_SQUARE;
- break;
- }
- switch(pGraphState->m_LineJoin) {
- case 0:
- PenStyle |= PS_JOIN_MITER;
- break;
- case 1:
- PenStyle |= PS_JOIN_ROUND;
- break;
- case 2:
- PenStyle |= PS_JOIN_BEVEL;
- break;
- }
- int a;
- FX_COLORREF rgb;
- ArgbDecode(argb, a, rgb);
- LOGBRUSH lb;
- lb.lbColor = rgb;
- lb.lbStyle = BS_SOLID;
- lb.lbHatch = 0;
- FX_DWORD* pDash = NULL;
- if (pGraphState->m_DashCount) {
- pDash = FX_Alloc(FX_DWORD, pGraphState->m_DashCount);
- if (!pDash) {
- return NULL;
- }
- for (int i = 0; i < pGraphState->m_DashCount; i ++) {
- pDash[i] = FXSYS_round(pMatrix ? pMatrix->TransformDistance(pGraphState->m_DashArray[i]) : pGraphState->m_DashArray[i]);
- if (pDash[i] < 1) {
- pDash[i] = 1;
- }
- }
- }
- HPEN hPen = ExtCreatePen(PenStyle, (DWORD)FXSYS_ceil(width), &lb, pGraphState->m_DashCount, (const DWORD*)pDash);
- if (pDash) {
- FX_Free(pDash);
- }
- return hPen;
-}
-static HBRUSH _CreateBrush(FX_DWORD argb)
-{
- int a;
- FX_COLORREF rgb;
- ArgbDecode(argb, a, rgb);
- return CreateSolidBrush(rgb);
-}
-static void _SetPathToDC(HDC hDC, const CFX_PathData* pPathData, const CFX_AffineMatrix* pMatrix)
-{
- BeginPath(hDC);
- int nPoints = pPathData->GetPointCount();
- FX_PATHPOINT* pPoints = pPathData->GetPoints();
- for(int i = 0; i < nPoints; i++) {
- FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY;
- if (pMatrix) {
- pMatrix->Transform(posx, posy);
- }
- int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy);
- int point_type = pPoints[i].m_Flag & FXPT_TYPE;
- if(point_type == PT_MOVETO) {
- MoveToEx(hDC, screen_x, screen_y, NULL);
- } else if(point_type == PT_LINETO) {
- if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY && pPoints[i].m_PointX == pPoints[i - 1].m_PointX) {
- screen_x ++;
- }
- LineTo(hDC, screen_x, screen_y);
- } else if(point_type == PT_BEZIERTO) {
- POINT lppt[3];
- lppt[0].x = screen_x;
- lppt[0].y = screen_y;
- posx = pPoints[i + 1].m_PointX;
- posy = pPoints[i + 1].m_PointY;
- if (pMatrix) {
- pMatrix->Transform(posx, posy);
- }
- lppt[1].x = FXSYS_round(posx);
- lppt[1].y = FXSYS_round(posy);
- posx = pPoints[i + 2].m_PointX;
- posy = pPoints[i + 2].m_PointY;
- if (pMatrix) {
- pMatrix->Transform(posx, posy);
- }
- lppt[2].x = FXSYS_round(posx);
- lppt[2].y = FXSYS_round(posy);
- PolyBezierTo(hDC, lppt, 3);
- i += 2;
- }
- if (pPoints[i].m_Flag & PT_CLOSEFIGURE) {
- CloseFigure(hDC);
- }
- }
- EndPath(hDC);
-}
-void CGdiDeviceDriver::DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2)
-{
- int flag1 = (x1 < 0) | ((x1 > m_Width) << 1) | ((y1 < 0) << 2) | ((y1 > m_Height) << 3);
- int flag2 = (x2 < 0) | ((x2 > m_Width) << 1) | ((y2 < 0) << 2) | ((y2 > m_Height) << 3);
- if (flag1 & flag2) {
- return;
- }
- if (flag1 || flag2) {
- agg::rect_base<FX_FLOAT> rect(0.0f, 0.0f, (FX_FLOAT)(m_Width), (FX_FLOAT)(m_Height));
- FX_FLOAT x[2], y[2];
- int np = agg::clip_liang_barsky<FX_FLOAT>(x1, y1, x2, y2, rect, x, y);
- if (np == 0) {
- return;
- }
- if (np == 1) {
- x2 = x[0];
- y2 = y[0];
- } else {
- x1 = x[0];
- y1 = y[0];
- x2 = x[np - 1];
- y2 = y[np - 1];
- }
- }
- MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
- LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
-}
-static FX_BOOL _MatrixNoScaled(const CFX_AffineMatrix* pMatrix)
-{
- return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 && pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f;
-}
-FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pMatrix,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color,
- FX_DWORD stroke_color,
- int fill_mode,
- int alpha_flag,
- void* pIccTransform,
- int blend_type
- )
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
- _Color2Argb(stroke_color, stroke_color, alpha_flag, pIccTransform);
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- if ((pGraphState == NULL || stroke_color == 0) && !pPlatform->m_GdiplusExt.IsAvailable()) {
- CFX_FloatRect bbox_f = pPathData->GetBoundingBox();
- if (pMatrix) {
- bbox_f.Transform(pMatrix);
- }
- FX_RECT bbox = bbox_f.GetInnerRect();
- if (bbox.Width() <= 0) {
- return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.bottom + 1), fill_color,
- alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
- } else if (bbox.Height() <= 0) {
- return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.right + 1), (FX_FLOAT)(bbox.top), fill_color,
- alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
- }
- }
- int fill_alpha = FXARGB_A(fill_color);
- int stroke_alpha = FXARGB_A(stroke_color);
- FX_BOOL bDrawAlpha = (fill_alpha > 0 && fill_alpha < 255) || (stroke_alpha > 0 && stroke_alpha < 255 && pGraphState);
- if (!pPlatform->m_GdiplusExt.IsAvailable() && bDrawAlpha) {
- return FALSE;
- }
- if (pPlatform->m_GdiplusExt.IsAvailable()) {
- if (bDrawAlpha || ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFILL_FULLCOVER)) || pGraphState && pGraphState->m_DashCount)) {
- if ( !((NULL == pMatrix || _MatrixNoScaled(pMatrix)) &&
- pGraphState && pGraphState->m_LineWidth == 1.f &&
- (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) &&
- pPathData->IsRect()) ) {
- if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix, pGraphState, fill_color, stroke_color, fill_mode)) {
- return TRUE;
- }
- }
- }
- }
- int old_fill_mode = fill_mode;
- fill_mode &= 3;
- HPEN hPen = NULL;
- HBRUSH hBrush = NULL;
- if (pGraphState && stroke_alpha) {
- SetMiterLimit(m_hDC, pGraphState->m_MiterLimit, NULL);
- hPen = _CreatePen(pGraphState, pMatrix, stroke_color);
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- }
- if (fill_mode && fill_alpha) {
- SetPolyFillMode(m_hDC, fill_mode);
- hBrush = _CreateBrush(fill_color);
- hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
- }
- if (pPathData->GetPointCount() == 2 && pGraphState && pGraphState->m_DashCount) {
- FX_FLOAT x1 = pPathData->GetPointX(0), y1 = pPathData->GetPointY(0);
- if (pMatrix) {
- pMatrix->Transform(x1, y1);
- }
- FX_FLOAT x2 = pPathData->GetPointX(1), y2 = pPathData->GetPointY(1);
- if (pMatrix) {
- pMatrix->Transform(x2, y2);
- }
- DrawLine(x1, y1, x2, y2);
- } else {
- _SetPathToDC(m_hDC, pPathData, pMatrix);
- if (pGraphState && stroke_alpha) {
- if (fill_mode && fill_alpha) {
- if (old_fill_mode & FX_FILL_TEXT_MODE) {
- StrokeAndFillPath(m_hDC);
- } else {
- FillPath(m_hDC);
- _SetPathToDC(m_hDC, pPathData, pMatrix);
- StrokePath(m_hDC);
- }
- } else {
- StrokePath(m_hDC);
- }
- } else if (fill_mode && fill_alpha) {
- FillPath(m_hDC);
- }
- }
- if (hPen) {
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- DeleteObject(hPen);
- }
- if (hBrush) {
- hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
- DeleteObject(hBrush);
- }
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
- int alpha;
- FX_COLORREF rgb;
- ArgbDecode(fill_color, alpha, rgb);
- if (alpha == 0) {
- return TRUE;
- }
- if (alpha < 255) {
- return FALSE;
- }
- HBRUSH hBrush = CreateSolidBrush(rgb);
- ::FillRect(m_hDC, (RECT*)pRect, hBrush);
- DeleteObject(hBrush);
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pMatrix,
- int fill_mode
- )
-{
- if (pPathData->GetPointCount() == 5) {
- CFX_FloatRect rectf;
- if (pPathData->IsRect(pMatrix, &rectf)) {
- FX_RECT rect = rectf.GetOutterRect();
- IntersectClipRect(m_hDC, rect.left, rect.top, rect.right, rect.bottom);
- return TRUE;
- }
- }
- _SetPathToDC(m_hDC, pPathData, pMatrix);
- SetPolyFillMode(m_hDC, fill_mode & 3);
- SelectClipPath(m_hDC, RGN_AND);
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pMatrix,
- const CFX_GraphStateData* pGraphState
- )
-{
- HPEN hPen = _CreatePen(pGraphState, pMatrix, 0xff000000);
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- _SetPathToDC(m_hDC, pPathData, pMatrix);
- WidenPath(m_hDC);
- SetPolyFillMode(m_hDC, WINDING);
- FX_BOOL ret = SelectClipPath(m_hDC, RGN_AND);
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- DeleteObject(hPen);
- return ret;
-}
-FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform);
- int a;
- FX_COLORREF rgb;
- ArgbDecode(color, a, rgb);
- if (a == 0) {
- return TRUE;
- }
- HPEN hPen = CreatePen(PS_SOLID, 1, rgb);
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
- LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
- hPen = (HPEN)SelectObject(m_hDC, hPen);
- DeleteObject(hPen);
- return TRUE;
-}
-FX_BOOL CGdiDeviceDriver::DeleteDeviceRgn(FX_LPVOID pRgn)
-{
- DeleteObject((HGDIOBJ)pRgn);
- return TRUE;
-}
-CGdiDisplayDriver::CGdiDisplayDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_DISPLAY)
-{
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- if (pPlatform->m_GdiplusExt.IsAvailable()) {
- m_RenderCaps |= FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE;
- }
-}
-FX_BOOL CGdiDisplayDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform, FX_BOOL bDEdge)
-{
- FX_BOOL ret = FALSE;
- int width = pBitmap->GetWidth();
- int height = pBitmap->GetHeight();
- HBITMAP hbmp = CreateCompatibleBitmap(m_hDC, width, height);
- HDC hDCMemory = CreateCompatibleDC(m_hDC);
- HBITMAP holdbmp = (HBITMAP)SelectObject(hDCMemory, hbmp);
- BitBlt(hDCMemory, 0, 0, width, height, m_hDC, left, top, SRCCOPY);
- SelectObject(hDCMemory, holdbmp);
- BITMAPINFO bmi;
- FXSYS_memset32(&bmi, 0, sizeof bmi);
- bmi.bmiHeader.biSize = sizeof bmi.bmiHeader;
- bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
- bmi.bmiHeader.biHeight = -height;
- bmi.bmiHeader.biPlanes = 1;
- bmi.bmiHeader.biWidth = width;
- if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
- pIccTransform = NULL;
- }
- if (pBitmap->GetBPP() > 8 && !pBitmap->IsCmykImage() && pIccTransform == NULL) {
- ret = ::GetDIBits(hDCMemory, hbmp, 0, height, pBitmap->GetBuffer(), &bmi, DIB_RGB_COLORS) == height;
- } else {
- CFX_DIBitmap bitmap;
- if (bitmap.Create(width, height, FXDIB_Rgb)) {
- bmi.bmiHeader.biBitCount = 24;
- ::GetDIBits(hDCMemory, hbmp, 0, height, bitmap.GetBuffer(), &bmi, DIB_RGB_COLORS);
- ret = pBitmap->TransferBitmap(0, 0, width, height, &bitmap, 0, 0, pIccTransform);
- } else {
- ret = FALSE;
- }
- }
-#ifndef _FPDFAPI_MINI_
- if (pBitmap->HasAlpha() && ret) {
- pBitmap->LoadChannel(FXDIB_Alpha, 0xff);
- }
-#endif
- DeleteObject(hbmp);
- DeleteObject(hDCMemory);
- return ret;
-}
-FX_BOOL CGdiDisplayDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform)
-{
- ASSERT(blend_type == FXDIB_BLEND_NORMAL);
- if (pSource->IsAlphaMask()) {
- int width = pSource->GetWidth(), height = pSource->GetHeight();
- int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
- FX_BOOL bGDI = pSource->GetBPP() == 1 && alpha == 255;
- if (!bGDI) {
- CFX_DIBitmap background;
- if (!background.Create(width, height, FXDIB_Rgb32) ||
- !GetDIBits(&background, left, top, NULL) ||
- !background.CompositeMask(0, 0, width, height, pSource, color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) {
- return FALSE;
- }
- FX_RECT src_rect(0, 0, width, height);
- return SetDIBits(&background, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL);
- }
- FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height());
- return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, width, height,
- &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
- } else {
- int width = pSrcRect->Width(), height = pSrcRect->Height();
- if (pSource->HasAlpha()) {
- CFX_DIBitmap bitmap;
- if (!bitmap.Create(width, height, FXDIB_Rgb) ||
- !GetDIBits(&bitmap, left, top, NULL) ||
- !bitmap.CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left, pSrcRect->top, FXDIB_BLEND_NORMAL, NULL, FALSE, pIccTransform)) {
- return FALSE;
- }
- FX_RECT src_rect(0, 0, width, height);
- return SetDIBits(&bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL);
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap) {
- return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
- }
- }
- return FALSE;
-}
-FX_BOOL CGdiDisplayDriver::UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- FX_RECT bitmap_clip = *pClipRect;
- if (dest_width < 0) {
- dest_left += dest_width;
- }
- if (dest_height < 0) {
- dest_top += dest_height;
- }
- bitmap_clip.Offset(-dest_left, -dest_top);
- CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, render_flags, &bitmap_clip);
- if (pStretched == NULL) {
- return TRUE;
- }
- FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight());
- FX_BOOL ret = SetDIBits(pStretched, color, &src_rect, pClipRect->left, pClipRect->top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform);
- delete pStretched;
- return ret;
-}
-FX_BOOL CGdiDisplayDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- ASSERT(pSource != NULL && pClipRect != NULL);
- if (flags || dest_width > 10000 || dest_width < -10000 || dest_height > 10000 || dest_height < -10000)
- return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
- pClipRect, flags, alpha_flag, pIccTransform, blend_type);
- if (pSource->IsAlphaMask()) {
- FX_RECT image_rect;
- image_rect.left = dest_width > 0 ? dest_left : dest_left + dest_width;
- image_rect.right = dest_width > 0 ? dest_left + dest_width : dest_left;
- image_rect.top = dest_height > 0 ? dest_top : dest_top + dest_height;
- image_rect.bottom = dest_height > 0 ? dest_top + dest_height : dest_top;
- FX_RECT clip_rect = image_rect;
- clip_rect.Intersect(*pClipRect);
- clip_rect.Offset(-image_rect.left, -image_rect.top);
- int clip_width = clip_rect.Width(), clip_height = clip_rect.Height();
- CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, flags, &clip_rect);
- if (pStretched == NULL) {
- return TRUE;
- }
- CFX_DIBitmap background;
- if (!background.Create(clip_width, clip_height, FXDIB_Rgb32) ||
- !GetDIBits(&background, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, NULL) ||
- !background.CompositeMask(0, 0, clip_width, clip_height, pStretched, color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) {
- delete pStretched;
- return FALSE;
- }
- FX_RECT src_rect(0, 0, clip_width, clip_height);
- FX_BOOL ret = SetDIBits(&background, 0, &src_rect, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL, 0, NULL);
- delete pStretched;
- return ret;
- } else {
- if (pSource->HasAlpha()) {
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- if (pPlatform->m_GdiplusExt.IsAvailable() && pIccTransform == NULL && !pSource->IsCmykImage()) {
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap == NULL) {
- return FALSE;
- }
- return pPlatform->m_GdiplusExt.StretchDIBits(m_hDC, pBitmap, dest_left, dest_top, dest_width, dest_height, pClipRect, flags);
- }
- return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
- pClipRect, flags, alpha_flag, pIccTransform, blend_type);
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap) {
- return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform);
- }
- }
- return FALSE;
-}
-#define GET_PS_FEATURESETTING 4121
-#define FEATURESETTING_PSLEVEL 2
-int GetPSLevel(HDC hDC)
-{
- int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
- if (device_type != DT_RASPRINTER) {
- return 0;
- }
- FX_DWORD esc = GET_PS_FEATURESETTING;
- if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
- int param = FEATURESETTING_PSLEVEL;
- if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
- return param;
- }
- }
- esc = POSTSCRIPT_IDENTIFY;
- if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL) == 0) {
- esc = POSTSCRIPT_DATA;
- if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
- return 2;
- }
- return 0;
- }
- esc = PSIDENT_GDICENTRIC;
- if (ExtEscape(hDC, POSTSCRIPT_IDENTIFY, sizeof(FX_DWORD), (char*)&esc, 0, NULL) <= 0) {
- return 2;
- }
- esc = GET_PS_FEATURESETTING;
- if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
- int param = FEATURESETTING_PSLEVEL;
- if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
- return param;
- }
- }
- return 2;
-}
-int CFX_WindowsDevice::m_psLevel = 2;
-CFX_WindowsDevice::CFX_WindowsDevice(HDC hDC, FX_BOOL bCmykOutput, FX_BOOL bForcePSOutput, int psLevel)
-{
- m_bForcePSOutput = bForcePSOutput;
- m_psLevel = psLevel;
- if (bForcePSOutput) {
- IFX_RenderDeviceDriver* pDriver = FX_NEW CPSPrinterDriver;
- if (!pDriver) {
- return;
- }
- ((CPSPrinterDriver*)pDriver)->Init(hDC, psLevel, bCmykOutput);
- SetDeviceDriver(pDriver);
- return;
- }
- SetDeviceDriver(CreateDriver(hDC, bCmykOutput));
-}
-HDC CFX_WindowsDevice::GetDC() const
-{
- IFX_RenderDeviceDriver *pRDD = GetDeviceDriver();
- if (!pRDD) {
- return NULL;
- }
- return (HDC)pRDD->GetPlatformSurface();
-}
-IFX_RenderDeviceDriver* CFX_WindowsDevice::CreateDriver(HDC hDC, FX_BOOL bCmykOutput)
-{
- int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
- int obj_type = ::GetObjectType(hDC);
- int device_class;
- if (device_type == DT_RASPRINTER || device_type == DT_PLOTTER || obj_type == OBJ_ENHMETADC) {
- device_class = FXDC_PRINTER;
- } else {
- device_class = FXDC_DISPLAY;
- }
- return FX_NEW CGdiDisplayDriver(hDC);
-}
-CFX_WinBitmapDevice::CFX_WinBitmapDevice(int width, int height, FXDIB_Format format)
-{
- BITMAPINFOHEADER bmih;
- FXSYS_memset32(&bmih, 0, sizeof (BITMAPINFOHEADER));
- bmih.biSize = sizeof(BITMAPINFOHEADER);
- bmih.biBitCount = format & 0xff;
- bmih.biHeight = -height;
- bmih.biPlanes = 1;
- bmih.biWidth = width;
- FX_LPBYTE pBuffer;
- m_hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (FX_LPVOID*)&pBuffer, NULL, 0);
- if (m_hBitmap == NULL) {
- return;
- }
- CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
- if (!pBitmap) {
- return;
- }
- pBitmap->Create(width, height, format, pBuffer);
- SetBitmap(pBitmap);
- m_hDC = ::CreateCompatibleDC(NULL);
- m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap);
- IFX_RenderDeviceDriver* pDriver = FX_NEW CGdiDisplayDriver(m_hDC);
- if (!pDriver) {
- return;
- }
- SetDeviceDriver(pDriver);
-}
-CFX_WinBitmapDevice::~CFX_WinBitmapDevice()
-{
- if (m_hDC) {
- SelectObject(m_hDC, m_hOldBitmap);
- DeleteDC(m_hDC);
- }
- if (m_hBitmap) {
- DeleteObject(m_hBitmap);
- }
- delete GetBitmap();
-}
-#endif
+// 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 "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include "../../../include/fxge/fx_ge_win32.h"
+#include <crtdbg.h>
+#include "../agg/include/fxfx_agg_clip_liang_barsky.h"
+#include "dwrite_int.h"
+#include "win32_int.h"
+#include "../ge/text_int.h"
+#include "../dib/dib_int.h"
+#include "../agg/include/fx_agg_driver.h"
+#include "../../../include/fxge/fx_freetype.h"
+#include "../../../include/fxcodec/fx_codec.h"
+class CWin32FontInfo : public IFX_SystemFontInfo
+{
+public:
+ CWin32FontInfo();
+ ~CWin32FontInfo();
+ virtual void Release();
+ virtual FX_BOOL EnumFontList(CFX_FontMapper* pMapper);
+ virtual void* MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR face, FX_BOOL& bExact);
+ virtual void* GetFont(FX_LPCSTR face)
+ {
+ return NULL;
+ }
+ virtual FX_DWORD GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size);
+ virtual void DeleteFont(void* hFont);
+ virtual FX_BOOL GetFaceName(void* hFont, CFX_ByteString& name);
+ virtual FX_BOOL GetFontCharset(void* hFont, int& charset);
+ FX_BOOL IsOpenTypeFromDiv(const LOGFONTA *plf);
+ FX_BOOL IsSupportFontFormDiv(const LOGFONTA* plf);
+ void AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType);
+ void GetGBPreference(CFX_ByteString& face, int weight, int picth_family);
+ void GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family);
+ CFX_ByteString FindFont(const CFX_ByteString& name);
+ HDC m_hDC;
+ CFX_FontMapper* m_pMapper;
+ CFX_ByteString m_LastFamily;
+ CFX_ByteString m_KaiTi, m_FangSong;
+};
+CWin32FontInfo::CWin32FontInfo()
+{
+ m_hDC = CreateCompatibleDC(NULL);
+}
+CWin32FontInfo::~CWin32FontInfo()
+{
+ m_pMapper = NULL;
+}
+void CWin32FontInfo::Release()
+{
+ DeleteDC(m_hDC);
+ delete this;
+}
+#define TT_MAKE_TAG(x1, x2, x3, x4) (((FX_DWORD)x1<<24)|((FX_DWORD)x2<<16)|((FX_DWORD)x3<<8)|(FX_DWORD)x4)
+FX_BOOL CWin32FontInfo::IsOpenTypeFromDiv(const LOGFONTA *plf)
+{
+ HFONT hFont = CreateFontIndirectA(plf);
+ FX_BOOL ret = FALSE;
+ FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
+ if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
+ FX_DWORD lVersion = 0;
+ GetFontData(hFont, 0, (FX_BYTE*)(&lVersion), sizeof(FX_DWORD));
+ lVersion = (((FX_DWORD)(FX_BYTE)(lVersion)) << 24) | ((FX_DWORD)((FX_BYTE)(lVersion >> 8))) << 16 |
+ ((FX_DWORD)((FX_BYTE)(lVersion >> 16))) << 8 | ((FX_BYTE)(lVersion >> 24));
+ if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
+ lVersion == 0x00010000 ||
+ lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
+ lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
+ lVersion == 0x00020000) {
+ ret = TRUE;
+ }
+ }
+ DeleteFont(hFont);
+ return ret;
+}
+FX_BOOL CWin32FontInfo::IsSupportFontFormDiv(const LOGFONTA* plf)
+{
+ HFONT hFont = CreateFontIndirectA(plf);
+ FX_BOOL ret = FALSE;
+ FX_DWORD font_size = GetFontData(hFont, 0, NULL, 0);
+ if (font_size != GDI_ERROR && font_size >= sizeof(FX_DWORD)) {
+ FX_DWORD lVersion = 0;
+ GetFontData(hFont, 0, (FX_BYTE*)(&lVersion), sizeof(FX_DWORD));
+ lVersion = (((FX_DWORD)(FX_BYTE)(lVersion)) << 24) | ((FX_DWORD)((FX_BYTE)(lVersion >> 8))) << 16 |
+ ((FX_DWORD)((FX_BYTE)(lVersion >> 16))) << 8 | ((FX_BYTE)(lVersion >> 24));
+ if (lVersion == TT_MAKE_TAG('O', 'T', 'T', 'O') ||
+ lVersion == 0x00010000 ||
+ lVersion == TT_MAKE_TAG('t', 't', 'c', 'f') ||
+ lVersion == TT_MAKE_TAG('t', 'r', 'u', 'e') ||
+ lVersion == 0x00020000) {
+ ret = TRUE;
+ } else if ((lVersion & 0xFFFF0000) == TT_MAKE_TAG(0x80, 0x01, 0x00, 0x00) ||
+ (lVersion & 0xFFFF0000) == TT_MAKE_TAG('%', '!', 0, 0)) {
+ ret = TRUE;
+ }
+ }
+ DeleteFont(hFont);
+ return ret;
+}
+void CWin32FontInfo::AddInstalledFont(const LOGFONTA *plf, FX_DWORD FontType)
+{
+ CFX_ByteString name(plf->lfFaceName, -1);
+ if (name[0] == '@') {
+ return;
+ }
+ if (name == m_LastFamily) {
+ m_pMapper->AddInstalledFont(name, plf->lfCharSet);
+ return;
+ }
+ if (!(FontType & TRUETYPE_FONTTYPE) && !(FontType & DEVICE_FONTTYPE)) {
+ return;
+ }
+ if (!(FontType & TRUETYPE_FONTTYPE)) {
+ if (!IsSupportFontFormDiv(plf)) {
+ return;
+ }
+ }
+ m_pMapper->AddInstalledFont(name, plf->lfCharSet);
+ m_LastFamily = name;
+}
+static int CALLBACK FontEnumProc(
+ const LOGFONTA *plf,
+ const TEXTMETRICA *lpntme,
+ FX_DWORD FontType,
+ LPARAM lParam
+)
+{
+ CWin32FontInfo* pFontInfo = (CWin32FontInfo*)lParam;
+ if (pFontInfo->m_pMapper->GetFontEnumerator()) {
+ pFontInfo->m_pMapper->GetFontEnumerator()->HitFont();
+ }
+ pFontInfo->AddInstalledFont(plf, FontType);
+ return 1;
+}
+FX_BOOL CWin32FontInfo::EnumFontList(CFX_FontMapper* pMapper)
+{
+ m_pMapper = pMapper;
+ LOGFONTA lf;
+ FXSYS_memset32(&lf, 0, sizeof(LOGFONTA));
+ lf.lfCharSet = DEFAULT_CHARSET;
+ lf.lfFaceName[0] = 0;
+ lf.lfPitchAndFamily = 0;
+ EnumFontFamiliesExA(m_hDC, &lf, (FONTENUMPROCA)FontEnumProc, (FX_UINTPTR)this, 0);
+ if (pMapper->GetFontEnumerator()) {
+ pMapper->GetFontEnumerator()->Finish();
+ }
+ return TRUE;
+}
+static const struct {
+ FX_LPCSTR m_pFaceName;
+ FX_LPCSTR m_pVariantName;
+}
+VariantNames[] = {
+ {"DFKai-SB", "\x19\x6A\x77\x69\xD4\x9A"},
+};
+static const struct {
+ FX_LPCSTR m_pName;
+ FX_LPCSTR m_pWinName;
+ FX_BOOL m_bBold;
+ FX_BOOL m_bItalic;
+}
+Base14Substs[] = {
+ {"Courier", "Courier New", FALSE, FALSE},
+ {"Courier-Bold", "Courier New", TRUE, FALSE},
+ {"Courier-BoldOblique", "Courier New", TRUE, TRUE},
+ {"Courier-Oblique", "Courier New", FALSE, TRUE},
+ {"Helvetica", "Arial", FALSE, FALSE},
+ {"Helvetica-Bold", "Arial", TRUE, FALSE},
+ {"Helvetica-BoldOblique", "Arial", TRUE, TRUE},
+ {"Helvetica-Oblique", "Arial", FALSE, TRUE},
+ {"Times-Roman", "Times New Roman", FALSE, FALSE},
+ {"Times-Bold", "Times New Roman", TRUE, FALSE},
+ {"Times-BoldItalic", "Times New Roman", TRUE, TRUE},
+ {"Times-Italic", "Times New Roman", FALSE, TRUE},
+};
+CFX_ByteString CWin32FontInfo::FindFont(const CFX_ByteString& name)
+{
+ if (m_pMapper == NULL) {
+ return name;
+ }
+ int nFonts = m_pMapper->m_InstalledTTFonts.GetSize();
+ for (int i = 0; i < nFonts; i ++) {
+ CFX_ByteString thisname = m_pMapper->m_InstalledTTFonts[i];
+ if (thisname[0] == ' ') {
+ if (thisname.Mid(1, name.GetLength()) == name) {
+ return m_pMapper->m_InstalledTTFonts[i + 1];
+ }
+ } else if (thisname.Left(name.GetLength()) == name) {
+ return m_pMapper->m_InstalledTTFonts[i];
+ }
+ }
+ return CFX_ByteString();
+}
+struct _FontNameMap {
+ FX_LPCSTR m_pSubFontName;
+ FX_LPCSTR m_pSrcFontName;
+};
+const _FontNameMap g_JpFontNameMap[] = {
+ {"MS Mincho", "Heiseimin-W3"},
+ {"MS Gothic", "Jun101-Light"},
+};
+const _FontNameMap g_GbFontNameMap[1];
+extern "C" {
+ static int compareString(const void* key, const void* element)
+ {
+ return FXSYS_stricmp((FX_LPCSTR)key, ((_FontNameMap*)element)->m_pSrcFontName);
+ }
+}
+FX_BOOL _GetSubFontName(CFX_ByteString& name, int lang)
+{
+ int size = sizeof g_JpFontNameMap;
+ void* pFontnameMap = (void*)g_JpFontNameMap;
+ if (lang == 1) {
+ size = sizeof g_GbFontNameMap;
+ pFontnameMap = (void*)g_GbFontNameMap;
+ } else if (lang == 2) {
+ size = 0;
+ }
+ _FontNameMap* found = (_FontNameMap*)FXSYS_bsearch((FX_LPCSTR)name, pFontnameMap,
+ size / sizeof (_FontNameMap), sizeof (_FontNameMap), compareString);
+ if (found == NULL) {
+ return FALSE;
+ }
+ name = found->m_pSubFontName;
+ return TRUE;
+}
+void CWin32FontInfo::GetGBPreference(CFX_ByteString& face, int weight, int picth_family)
+{
+ if (face.Find("KaiTi") >= 0 || face.Find("\xbf\xac") >= 0) {
+ if (m_KaiTi.IsEmpty()) {
+ m_KaiTi = FindFont("KaiTi");
+ if (m_KaiTi.IsEmpty()) {
+ m_KaiTi = "SimSun";
+ }
+ }
+ face = m_KaiTi;
+ } else if (face.Find("FangSong") >= 0 || face.Find("\xb7\xc2\xcb\xce") >= 0) {
+ if (m_FangSong.IsEmpty()) {
+ m_FangSong = FindFont("FangSong");
+ if (m_FangSong.IsEmpty()) {
+ m_FangSong = "SimSun";
+ }
+ }
+ face = m_FangSong;
+ } else if (face.Find("SimSun") >= 0 || face.Find("\xcb\xce") >= 0) {
+ face = "SimSun";
+ } else if (face.Find("SimHei") >= 0 || face.Find("\xba\xda") >= 0) {
+ face = "SimHei";
+ } else if (!(picth_family & FF_ROMAN) && weight > 550) {
+ face = "SimHei";
+ } else {
+ face = "SimSun";
+ }
+}
+void CWin32FontInfo::GetJapanesePreference(CFX_ByteString& face, int weight, int picth_family)
+{
+ if (face.Find("Gothic") >= 0 || face.Find("\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
+ if (face.Find("PGothic") >= 0 || face.Find("\x82\x6f\x83\x53\x83\x56\x83\x62\x83\x4e") >= 0) {
+ face = "MS PGothic";
+ } else if (face.Find("UI Gothic") >= 0) {
+ face = "MS UI Gothic";
+ } else {
+ if (face.Find("HGSGothicM") >= 0 || face.Find("HGMaruGothicMPRO") >= 0) {
+ face = "MS PGothic";
+ } else {
+ face = "MS Gothic";
+ }
+ }
+ return;
+ } else if (face.Find("Mincho") >= 0 || face.Find("\x96\xbe\x92\xa9") >= 0) {
+ if (face.Find("PMincho") >= 0 || face.Find("\x82\x6f\x96\xbe\x92\xa9") >= 0) {
+ face = "MS PMincho";
+ } else {
+ face = "MS Mincho";
+ }
+ return;
+ }
+ if (_GetSubFontName(face, 0)) {
+ return;
+ }
+ if (!(picth_family & FF_ROMAN) && weight > 400) {
+ face = "MS PGothic";
+ } else {
+ face = "MS PMincho";
+ }
+}
+void* CWin32FontInfo::MapFont(int weight, FX_BOOL bItalic, int charset, int pitch_family, FX_LPCSTR cstr_face, FX_BOOL& bExact)
+{
+ CFX_ByteString face = cstr_face;
+ int iBaseFont;
+ for (iBaseFont = 0; iBaseFont < 12; iBaseFont ++)
+ if (face == CFX_ByteStringC(Base14Substs[iBaseFont].m_pName)) {
+ face = Base14Substs[iBaseFont].m_pWinName;
+ weight = Base14Substs[iBaseFont].m_bBold ? FW_BOLD : FW_NORMAL;
+ bItalic = Base14Substs[iBaseFont].m_bItalic;
+ bExact = TRUE;
+ break;
+ }
+ if (charset == ANSI_CHARSET || charset == SYMBOL_CHARSET) {
+ charset = DEFAULT_CHARSET;
+ }
+ int subst_pitch_family = pitch_family;
+ switch (charset) {
+ case SHIFTJIS_CHARSET:
+ subst_pitch_family = FF_ROMAN;
+ break;
+ case CHINESEBIG5_CHARSET:
+ case HANGUL_CHARSET:
+ case GB2312_CHARSET:
+ subst_pitch_family = 0;
+ break;
+ }
+ HFONT hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
+ 0, 0, subst_pitch_family, face);
+ char facebuf[100];
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, hFont);
+ int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
+ ::SelectObject(m_hDC, hOldFont);
+ if (face.EqualNoCase(facebuf)) {
+ return hFont;
+ }
+ int iCount = sizeof(VariantNames) / sizeof(VariantNames[0]);
+ for (int i = 0; i < iCount; ++i) {
+ if (face == VariantNames[i].m_pFaceName) {
+ CFX_WideString wsFace = CFX_WideString::FromLocal(facebuf);
+ CFX_WideString wsName = CFX_WideString::FromUTF16LE((const unsigned short*)VariantNames[i].m_pVariantName);
+ if (wsFace == wsName) {
+ return hFont;
+ }
+ }
+ }
+ ::DeleteObject(hFont);
+ if (charset == DEFAULT_CHARSET) {
+ return NULL;
+ }
+ switch (charset) {
+ case SHIFTJIS_CHARSET:
+ GetJapanesePreference(face, weight, pitch_family);
+ break;
+ case GB2312_CHARSET:
+ GetGBPreference(face, weight, pitch_family);
+ break;
+ case HANGUL_CHARSET:
+ face = "Gulim";
+ break;
+ case CHINESEBIG5_CHARSET:
+ if (face.Find("MSung") >= 0) {
+ face = "MingLiU";
+ } else {
+ face = "PMingLiU";
+ }
+ break;
+ }
+ hFont = ::CreateFontA(-10, 0, 0, 0, weight, bItalic, 0, 0, charset, OUT_TT_ONLY_PRECIS,
+ 0, 0, subst_pitch_family, face);
+ return hFont;
+}
+void CWin32FontInfo::DeleteFont(void* hFont)
+{
+ ::DeleteObject(hFont);
+}
+FX_DWORD CWin32FontInfo::GetFontData(void* hFont, FX_DWORD table, FX_LPBYTE buffer, FX_DWORD size)
+{
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
+ table = FXDWORD_FROM_MSBFIRST(table);
+ size = ::GetFontData(m_hDC, table, 0, buffer, size);
+ ::SelectObject(m_hDC, hOldFont);
+ if (size == GDI_ERROR) {
+ return 0;
+ }
+ return size;
+}
+FX_BOOL CWin32FontInfo::GetFaceName(void* hFont, CFX_ByteString& name)
+{
+ char facebuf[100];
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
+ int ret = ::GetTextFaceA(m_hDC, 100, facebuf);
+ ::SelectObject(m_hDC, hOldFont);
+ if (ret == 0) {
+ return FALSE;
+ }
+ name = facebuf;
+ return TRUE;
+}
+FX_BOOL CWin32FontInfo::GetFontCharset(void* hFont, int& charset)
+{
+ TEXTMETRIC tm;
+ HFONT hOldFont = (HFONT)::SelectObject(m_hDC, (HFONT)hFont);
+ ::GetTextMetrics(m_hDC, &tm);
+ ::SelectObject(m_hDC, hOldFont);
+ charset = tm.tmCharSet;
+ return TRUE;
+}
+#ifndef _FPDFAPI_MINI_
+IFX_SystemFontInfo* IFX_SystemFontInfo::CreateDefault()
+{
+ return FX_NEW CWin32FontInfo;
+}
+#endif
+void CFX_GEModule::InitPlatform()
+{
+ CWin32Platform* pPlatformData = FX_NEW CWin32Platform;
+ if (!pPlatformData) {
+ return;
+ }
+ OSVERSIONINFO ver;
+ ver.dwOSVersionInfoSize = sizeof(ver);
+ GetVersionEx(&ver);
+ pPlatformData->m_bHalfTone = ver.dwMajorVersion >= 5;
+ pPlatformData->m_GdiplusExt.Load();
+ m_pPlatformData = pPlatformData;
+ m_pFontMgr->SetSystemFontInfo(IFX_SystemFontInfo::CreateDefault());
+}
+void CFX_GEModule::DestroyPlatform()
+{
+ if (m_pPlatformData) {
+ delete (CWin32Platform*)m_pPlatformData;
+ }
+ m_pPlatformData = NULL;
+}
+CGdiDeviceDriver::CGdiDeviceDriver(HDC hDC, int device_class)
+{
+ m_hDC = hDC;
+ m_DeviceClass = device_class;
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ SetStretchBltMode(hDC, pPlatform->m_bHalfTone ? HALFTONE : COLORONCOLOR);
+ if (GetObjectType(m_hDC) == OBJ_MEMDC) {
+ HBITMAP hBitmap = CreateBitmap(1, 1, 1, 1, NULL);
+ hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap);
+ BITMAP bitmap;
+ GetObject(hBitmap, sizeof bitmap, &bitmap);
+ m_nBitsPerPixel = bitmap.bmBitsPixel;
+ m_Width = bitmap.bmWidth;
+ m_Height = abs(bitmap.bmHeight);
+ hBitmap = (HBITMAP)SelectObject(m_hDC, hBitmap);
+ DeleteObject(hBitmap);
+ } else {
+ m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL);
+ m_Width = ::GetDeviceCaps(m_hDC, HORZRES);
+ m_Height = ::GetDeviceCaps(m_hDC, VERTRES);
+ }
+ if (m_DeviceClass != FXDC_DISPLAY) {
+ m_RenderCaps = FXRC_BIT_MASK;
+ } else {
+ m_RenderCaps = FXRC_GET_BITS | FXRC_BIT_MASK;
+ }
+}
+int CGdiDeviceDriver::GetDeviceCaps(int caps_id)
+{
+ switch (caps_id) {
+ case FXDC_DEVICE_CLASS:
+ return m_DeviceClass;
+ case FXDC_PIXEL_WIDTH:
+ return m_Width;
+ case FXDC_PIXEL_HEIGHT:
+ return m_Height;
+ case FXDC_BITS_PIXEL:
+ return m_nBitsPerPixel;
+ case FXDC_RENDER_CAPS:
+ return m_RenderCaps;
+ }
+ return 0;
+}
+FX_LPVOID CGdiDeviceDriver::GetClipRgn()
+{
+ HRGN hClipRgn = CreateRectRgn(0, 0, 1, 1);
+ if (::GetClipRgn(m_hDC, hClipRgn) == 0) {
+ DeleteObject(hClipRgn);
+ hClipRgn = NULL;
+ }
+ return (FX_LPVOID)hClipRgn;
+}
+FX_BOOL CGdiDeviceDriver::GDI_SetDIBits(const CFX_DIBitmap* pBitmap1, const FX_RECT* pSrcRect, int left, int top, void* pIccTransform)
+{
+ if (m_DeviceClass == FXDC_PRINTER) {
+ CFX_DIBitmap* pBitmap = pBitmap1->FlipImage(FALSE, TRUE);
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ if ((pBitmap->IsCmykImage() || pIccTransform) &&
+ !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
+ return FALSE;
+ }
+ int width = pSrcRect->Width(), height = pSrcRect->Height();
+ int pitch = pBitmap->GetPitch();
+ LPBYTE pBuffer = pBitmap->GetBuffer();
+ CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
+ ((BITMAPINFOHEADER*)(FX_LPCSTR)info)->biHeight *= -1;
+ FX_RECT dst_rect(0, 0, width, height);
+ dst_rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
+ int dst_width = dst_rect.Width();
+ int dst_height = dst_rect.Height();
+ ::StretchDIBits(m_hDC, left, top, dst_width, dst_height,
+ 0, 0, dst_width, dst_height, pBuffer, (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS, SRCCOPY);
+ delete pBitmap;
+ } else {
+ CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
+ if ((pBitmap->IsCmykImage() || pIccTransform) &&
+ (pBitmap = pBitmap->CloneConvert(FXDIB_Rgb, NULL, pIccTransform)) == NULL) {
+ return FALSE;
+ }
+ int width = pSrcRect->Width(), height = pSrcRect->Height();
+ int pitch = pBitmap->GetPitch();
+ LPBYTE pBuffer = pBitmap->GetBuffer();
+ CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
+ ::SetDIBitsToDevice(m_hDC, left, top, width, height, pSrcRect->left, pBitmap->GetHeight() - pSrcRect->bottom,
+ 0, pBitmap->GetHeight(), pBuffer, (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
+ if (pBitmap != pBitmap1) {
+ delete pBitmap;
+ }
+ }
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::GDI_StretchDIBits(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD flags, void* pIccTransform)
+{
+ CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ if ((pBitmap->IsCmykImage() || pIccTransform) &&
+ !pBitmap->ConvertFormat(FXDIB_Rgb, pIccTransform)) {
+ return FALSE;
+ }
+ CFX_ByteString info = CFX_WindowsDIB::GetBitmapInfo(pBitmap);
+ if (abs(dest_width) * abs(dest_height) < pBitmap1->GetWidth() * pBitmap1->GetHeight() * 4 ||
+ (flags & FXDIB_INTERPOL) || (flags & FXDIB_BICUBIC_INTERPOL)) {
+ SetStretchBltMode(m_hDC, HALFTONE);
+ } else {
+ SetStretchBltMode(m_hDC, COLORONCOLOR);
+ }
+ CFX_DIBitmap* pToStrechBitmap = pBitmap;
+ bool del = false;
+ if (m_DeviceClass == FXDC_PRINTER && (pBitmap->GetWidth() * pBitmap->GetHeight() > abs(dest_width) * abs(dest_height))) {
+ pToStrechBitmap = pBitmap->StretchTo(dest_width, dest_height);
+ del = true;
+ }
+ CFX_ByteString toStrechBitmapInfo = CFX_WindowsDIB::GetBitmapInfo(pToStrechBitmap);
+ ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
+ 0, 0, pToStrechBitmap->GetWidth(), pToStrechBitmap->GetHeight(), pToStrechBitmap->GetBuffer(),
+ (BITMAPINFO*)(FX_LPCSTR)toStrechBitmapInfo, DIB_RGB_COLORS, SRCCOPY);
+ if (del) {
+ delete pToStrechBitmap;
+ }
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::GDI_StretchBitMask(const CFX_DIBitmap* pBitmap1, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform)
+{
+ CFX_DIBitmap* pBitmap = (CFX_DIBitmap*)pBitmap1;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ _Color2Argb(bitmap_color, bitmap_color, alpha_flag | (1 << 24), pIccTransform);
+ int width = pBitmap->GetWidth(), height = pBitmap->GetHeight();
+ struct {
+ BITMAPINFOHEADER bmiHeader;
+ FX_DWORD bmiColors[2];
+ } bmi;
+ FXSYS_memset32(&bmi.bmiHeader, 0, sizeof (BITMAPINFOHEADER));
+ bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmi.bmiHeader.biBitCount = 1;
+ bmi.bmiHeader.biCompression = BI_RGB;
+ bmi.bmiHeader.biHeight = -height;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biWidth = width;
+ if (m_nBitsPerPixel != 1) {
+ SetStretchBltMode(m_hDC, HALFTONE);
+ }
+ bmi.bmiColors[0] = 0xffffff;
+ bmi.bmiColors[1] = 0;
+ ::StretchDIBits(m_hDC, dest_left, dest_top, dest_width, dest_height,
+ 0, 0, width, height, pBitmap->GetBuffer(), (BITMAPINFO*)&bmi, DIB_RGB_COLORS, SRCAND);
+ return TRUE;
+}
+BOOL CGdiDeviceDriver::GetClipBox(FX_RECT* pRect)
+{
+ return ::GetClipBox(m_hDC, (RECT*)pRect);
+}
+FX_BOOL CGdiDeviceDriver::SetClipRgn(FX_LPVOID hRgn)
+{
+ ::SelectClipRgn(m_hDC, (HRGN)hRgn);
+ return TRUE;
+}
+static HPEN _CreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, FX_DWORD argb)
+{
+ FX_FLOAT width;
+ FX_FLOAT scale = 1.f;
+ if (pMatrix)
+ scale = FXSYS_fabs(pMatrix->a) > FXSYS_fabs(pMatrix->b) ?
+ FXSYS_fabs(pMatrix->a) : FXSYS_fabs(pMatrix->b);
+ if (pGraphState) {
+ width = scale * pGraphState->m_LineWidth;
+ } else {
+ width = 1.0f;
+ }
+ FX_DWORD PenStyle = PS_GEOMETRIC;
+ if (width < 1) {
+ width = 1;
+ }
+ if(pGraphState->m_DashCount) {
+ PenStyle |= PS_USERSTYLE;
+ } else {
+ PenStyle |= PS_SOLID;
+ }
+ switch(pGraphState->m_LineCap) {
+ case 0:
+ PenStyle |= PS_ENDCAP_FLAT;
+ break;
+ case 1:
+ PenStyle |= PS_ENDCAP_ROUND;
+ break;
+ case 2:
+ PenStyle |= PS_ENDCAP_SQUARE;
+ break;
+ }
+ switch(pGraphState->m_LineJoin) {
+ case 0:
+ PenStyle |= PS_JOIN_MITER;
+ break;
+ case 1:
+ PenStyle |= PS_JOIN_ROUND;
+ break;
+ case 2:
+ PenStyle |= PS_JOIN_BEVEL;
+ break;
+ }
+ int a;
+ FX_COLORREF rgb;
+ ArgbDecode(argb, a, rgb);
+ LOGBRUSH lb;
+ lb.lbColor = rgb;
+ lb.lbStyle = BS_SOLID;
+ lb.lbHatch = 0;
+ FX_DWORD* pDash = NULL;
+ if (pGraphState->m_DashCount) {
+ pDash = FX_Alloc(FX_DWORD, pGraphState->m_DashCount);
+ if (!pDash) {
+ return NULL;
+ }
+ for (int i = 0; i < pGraphState->m_DashCount; i ++) {
+ pDash[i] = FXSYS_round(pMatrix ? pMatrix->TransformDistance(pGraphState->m_DashArray[i]) : pGraphState->m_DashArray[i]);
+ if (pDash[i] < 1) {
+ pDash[i] = 1;
+ }
+ }
+ }
+ HPEN hPen = ExtCreatePen(PenStyle, (DWORD)FXSYS_ceil(width), &lb, pGraphState->m_DashCount, (const DWORD*)pDash);
+ if (pDash) {
+ FX_Free(pDash);
+ }
+ return hPen;
+}
+static HBRUSH _CreateBrush(FX_DWORD argb)
+{
+ int a;
+ FX_COLORREF rgb;
+ ArgbDecode(argb, a, rgb);
+ return CreateSolidBrush(rgb);
+}
+static void _SetPathToDC(HDC hDC, const CFX_PathData* pPathData, const CFX_AffineMatrix* pMatrix)
+{
+ BeginPath(hDC);
+ int nPoints = pPathData->GetPointCount();
+ FX_PATHPOINT* pPoints = pPathData->GetPoints();
+ for(int i = 0; i < nPoints; i++) {
+ FX_FLOAT posx = pPoints[i].m_PointX, posy = pPoints[i].m_PointY;
+ if (pMatrix) {
+ pMatrix->Transform(posx, posy);
+ }
+ int screen_x = FXSYS_round(posx), screen_y = FXSYS_round(posy);
+ int point_type = pPoints[i].m_Flag & FXPT_TYPE;
+ if(point_type == PT_MOVETO) {
+ MoveToEx(hDC, screen_x, screen_y, NULL);
+ } else if(point_type == PT_LINETO) {
+ if (pPoints[i].m_PointY == pPoints[i - 1].m_PointY && pPoints[i].m_PointX == pPoints[i - 1].m_PointX) {
+ screen_x ++;
+ }
+ LineTo(hDC, screen_x, screen_y);
+ } else if(point_type == PT_BEZIERTO) {
+ POINT lppt[3];
+ lppt[0].x = screen_x;
+ lppt[0].y = screen_y;
+ posx = pPoints[i + 1].m_PointX;
+ posy = pPoints[i + 1].m_PointY;
+ if (pMatrix) {
+ pMatrix->Transform(posx, posy);
+ }
+ lppt[1].x = FXSYS_round(posx);
+ lppt[1].y = FXSYS_round(posy);
+ posx = pPoints[i + 2].m_PointX;
+ posy = pPoints[i + 2].m_PointY;
+ if (pMatrix) {
+ pMatrix->Transform(posx, posy);
+ }
+ lppt[2].x = FXSYS_round(posx);
+ lppt[2].y = FXSYS_round(posy);
+ PolyBezierTo(hDC, lppt, 3);
+ i += 2;
+ }
+ if (pPoints[i].m_Flag & PT_CLOSEFIGURE) {
+ CloseFigure(hDC);
+ }
+ }
+ EndPath(hDC);
+}
+void CGdiDeviceDriver::DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2)
+{
+ int flag1 = (x1 < 0) | ((x1 > m_Width) << 1) | ((y1 < 0) << 2) | ((y1 > m_Height) << 3);
+ int flag2 = (x2 < 0) | ((x2 > m_Width) << 1) | ((y2 < 0) << 2) | ((y2 > m_Height) << 3);
+ if (flag1 & flag2) {
+ return;
+ }
+ if (flag1 || flag2) {
+ agg::rect_base<FX_FLOAT> rect(0.0f, 0.0f, (FX_FLOAT)(m_Width), (FX_FLOAT)(m_Height));
+ FX_FLOAT x[2], y[2];
+ int np = agg::clip_liang_barsky<FX_FLOAT>(x1, y1, x2, y2, rect, x, y);
+ if (np == 0) {
+ return;
+ }
+ if (np == 1) {
+ x2 = x[0];
+ y2 = y[0];
+ } else {
+ x1 = x[0];
+ y1 = y[0];
+ x2 = x[np - 1];
+ y2 = y[np - 1];
+ }
+ }
+ MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
+ LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
+}
+static FX_BOOL _MatrixNoScaled(const CFX_AffineMatrix* pMatrix)
+{
+ return pMatrix->GetA() == 1.0f && pMatrix->GetB() == 0 && pMatrix->GetC() == 0 && pMatrix->GetD() == 1.0f;
+}
+FX_BOOL CGdiDeviceDriver::DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pMatrix,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type
+ )
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
+ _Color2Argb(stroke_color, stroke_color, alpha_flag, pIccTransform);
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ if ((pGraphState == NULL || stroke_color == 0) && !pPlatform->m_GdiplusExt.IsAvailable()) {
+ CFX_FloatRect bbox_f = pPathData->GetBoundingBox();
+ if (pMatrix) {
+ bbox_f.Transform(pMatrix);
+ }
+ FX_RECT bbox = bbox_f.GetInnerRect();
+ if (bbox.Width() <= 0) {
+ return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.bottom + 1), fill_color,
+ alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
+ } else if (bbox.Height() <= 0) {
+ return DrawCosmeticLine((FX_FLOAT)(bbox.left), (FX_FLOAT)(bbox.top), (FX_FLOAT)(bbox.right + 1), (FX_FLOAT)(bbox.top), fill_color,
+ alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
+ }
+ }
+ int fill_alpha = FXARGB_A(fill_color);
+ int stroke_alpha = FXARGB_A(stroke_color);
+ FX_BOOL bDrawAlpha = (fill_alpha > 0 && fill_alpha < 255) || (stroke_alpha > 0 && stroke_alpha < 255 && pGraphState);
+ if (!pPlatform->m_GdiplusExt.IsAvailable() && bDrawAlpha) {
+ return FALSE;
+ }
+ if (pPlatform->m_GdiplusExt.IsAvailable()) {
+ if (bDrawAlpha || ((m_DeviceClass != FXDC_PRINTER && !(fill_mode & FXFILL_FULLCOVER)) || pGraphState && pGraphState->m_DashCount)) {
+ if ( !((NULL == pMatrix || _MatrixNoScaled(pMatrix)) &&
+ pGraphState && pGraphState->m_LineWidth == 1.f &&
+ (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) &&
+ pPathData->IsRect()) ) {
+ if (pPlatform->m_GdiplusExt.DrawPath(m_hDC, pPathData, pMatrix, pGraphState, fill_color, stroke_color, fill_mode)) {
+ return TRUE;
+ }
+ }
+ }
+ }
+ int old_fill_mode = fill_mode;
+ fill_mode &= 3;
+ HPEN hPen = NULL;
+ HBRUSH hBrush = NULL;
+ if (pGraphState && stroke_alpha) {
+ SetMiterLimit(m_hDC, pGraphState->m_MiterLimit, NULL);
+ hPen = _CreatePen(pGraphState, pMatrix, stroke_color);
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ }
+ if (fill_mode && fill_alpha) {
+ SetPolyFillMode(m_hDC, fill_mode);
+ hBrush = _CreateBrush(fill_color);
+ hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
+ }
+ if (pPathData->GetPointCount() == 2 && pGraphState && pGraphState->m_DashCount) {
+ FX_FLOAT x1 = pPathData->GetPointX(0), y1 = pPathData->GetPointY(0);
+ if (pMatrix) {
+ pMatrix->Transform(x1, y1);
+ }
+ FX_FLOAT x2 = pPathData->GetPointX(1), y2 = pPathData->GetPointY(1);
+ if (pMatrix) {
+ pMatrix->Transform(x2, y2);
+ }
+ DrawLine(x1, y1, x2, y2);
+ } else {
+ _SetPathToDC(m_hDC, pPathData, pMatrix);
+ if (pGraphState && stroke_alpha) {
+ if (fill_mode && fill_alpha) {
+ if (old_fill_mode & FX_FILL_TEXT_MODE) {
+ StrokeAndFillPath(m_hDC);
+ } else {
+ FillPath(m_hDC);
+ _SetPathToDC(m_hDC, pPathData, pMatrix);
+ StrokePath(m_hDC);
+ }
+ } else {
+ StrokePath(m_hDC);
+ }
+ } else if (fill_mode && fill_alpha) {
+ FillPath(m_hDC);
+ }
+ }
+ if (hPen) {
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ DeleteObject(hPen);
+ }
+ if (hBrush) {
+ hBrush = (HBRUSH)SelectObject(m_hDC, hBrush);
+ DeleteObject(hBrush);
+ }
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::FillRect(const FX_RECT* pRect, FX_DWORD fill_color, int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ _Color2Argb(fill_color, fill_color, alpha_flag | (1 << 24), pIccTransform);
+ int alpha;
+ FX_COLORREF rgb;
+ ArgbDecode(fill_color, alpha, rgb);
+ if (alpha == 0) {
+ return TRUE;
+ }
+ if (alpha < 255) {
+ return FALSE;
+ }
+ HBRUSH hBrush = CreateSolidBrush(rgb);
+ ::FillRect(m_hDC, (RECT*)pRect, hBrush);
+ DeleteObject(hBrush);
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pMatrix,
+ int fill_mode
+ )
+{
+ if (pPathData->GetPointCount() == 5) {
+ CFX_FloatRect rectf;
+ if (pPathData->IsRect(pMatrix, &rectf)) {
+ FX_RECT rect = rectf.GetOutterRect();
+ IntersectClipRect(m_hDC, rect.left, rect.top, rect.right, rect.bottom);
+ return TRUE;
+ }
+ }
+ _SetPathToDC(m_hDC, pPathData, pMatrix);
+ SetPolyFillMode(m_hDC, fill_mode & 3);
+ SelectClipPath(m_hDC, RGN_AND);
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pMatrix,
+ const CFX_GraphStateData* pGraphState
+ )
+{
+ HPEN hPen = _CreatePen(pGraphState, pMatrix, 0xff000000);
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ _SetPathToDC(m_hDC, pPathData, pMatrix);
+ WidenPath(m_hDC);
+ SetPolyFillMode(m_hDC, WINDING);
+ FX_BOOL ret = SelectClipPath(m_hDC, RGN_AND);
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ DeleteObject(hPen);
+ return ret;
+}
+FX_BOOL CGdiDeviceDriver::DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ _Color2Argb(color, color, alpha_flag | (1 << 24), pIccTransform);
+ int a;
+ FX_COLORREF rgb;
+ ArgbDecode(color, a, rgb);
+ if (a == 0) {
+ return TRUE;
+ }
+ HPEN hPen = CreatePen(PS_SOLID, 1, rgb);
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ MoveToEx(m_hDC, FXSYS_round(x1), FXSYS_round(y1), NULL);
+ LineTo(m_hDC, FXSYS_round(x2), FXSYS_round(y2));
+ hPen = (HPEN)SelectObject(m_hDC, hPen);
+ DeleteObject(hPen);
+ return TRUE;
+}
+FX_BOOL CGdiDeviceDriver::DeleteDeviceRgn(FX_LPVOID pRgn)
+{
+ DeleteObject((HGDIOBJ)pRgn);
+ return TRUE;
+}
+CGdiDisplayDriver::CGdiDisplayDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_DISPLAY)
+{
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ if (pPlatform->m_GdiplusExt.IsAvailable()) {
+ m_RenderCaps |= FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE;
+ }
+}
+FX_BOOL CGdiDisplayDriver::GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform, FX_BOOL bDEdge)
+{
+ FX_BOOL ret = FALSE;
+ int width = pBitmap->GetWidth();
+ int height = pBitmap->GetHeight();
+ HBITMAP hbmp = CreateCompatibleBitmap(m_hDC, width, height);
+ HDC hDCMemory = CreateCompatibleDC(m_hDC);
+ HBITMAP holdbmp = (HBITMAP)SelectObject(hDCMemory, hbmp);
+ BitBlt(hDCMemory, 0, 0, width, height, m_hDC, left, top, SRCCOPY);
+ SelectObject(hDCMemory, holdbmp);
+ BITMAPINFO bmi;
+ FXSYS_memset32(&bmi, 0, sizeof bmi);
+ bmi.bmiHeader.biSize = sizeof bmi.bmiHeader;
+ bmi.bmiHeader.biBitCount = pBitmap->GetBPP();
+ bmi.bmiHeader.biHeight = -height;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biWidth = width;
+ if (!CFX_GEModule::Get()->GetCodecModule() || !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
+ pIccTransform = NULL;
+ }
+ if (pBitmap->GetBPP() > 8 && !pBitmap->IsCmykImage() && pIccTransform == NULL) {
+ ret = ::GetDIBits(hDCMemory, hbmp, 0, height, pBitmap->GetBuffer(), &bmi, DIB_RGB_COLORS) == height;
+ } else {
+ CFX_DIBitmap bitmap;
+ if (bitmap.Create(width, height, FXDIB_Rgb)) {
+ bmi.bmiHeader.biBitCount = 24;
+ ::GetDIBits(hDCMemory, hbmp, 0, height, bitmap.GetBuffer(), &bmi, DIB_RGB_COLORS);
+ ret = pBitmap->TransferBitmap(0, 0, width, height, &bitmap, 0, 0, pIccTransform);
+ } else {
+ ret = FALSE;
+ }
+ }
+#ifndef _FPDFAPI_MINI_
+ if (pBitmap->HasAlpha() && ret) {
+ pBitmap->LoadChannel(FXDIB_Alpha, 0xff);
+ }
+#endif
+ DeleteObject(hbmp);
+ DeleteObject(hDCMemory);
+ return ret;
+}
+FX_BOOL CGdiDisplayDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform)
+{
+ ASSERT(blend_type == FXDIB_BLEND_NORMAL);
+ if (pSource->IsAlphaMask()) {
+ int width = pSource->GetWidth(), height = pSource->GetHeight();
+ int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
+ FX_BOOL bGDI = pSource->GetBPP() == 1 && alpha == 255;
+ if (!bGDI) {
+ CFX_DIBitmap background;
+ if (!background.Create(width, height, FXDIB_Rgb32) ||
+ !GetDIBits(&background, left, top, NULL) ||
+ !background.CompositeMask(0, 0, width, height, pSource, color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) {
+ return FALSE;
+ }
+ FX_RECT src_rect(0, 0, width, height);
+ return SetDIBits(&background, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL);
+ }
+ FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height());
+ return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, width, height,
+ &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
+ } else {
+ int width = pSrcRect->Width(), height = pSrcRect->Height();
+ if (pSource->HasAlpha()) {
+ CFX_DIBitmap bitmap;
+ if (!bitmap.Create(width, height, FXDIB_Rgb) ||
+ !GetDIBits(&bitmap, left, top, NULL) ||
+ !bitmap.CompositeBitmap(0, 0, width, height, pSource, pSrcRect->left, pSrcRect->top, FXDIB_BLEND_NORMAL, NULL, FALSE, pIccTransform)) {
+ return FALSE;
+ }
+ FX_RECT src_rect(0, 0, width, height);
+ return SetDIBits(&bitmap, 0, &src_rect, left, top, FXDIB_BLEND_NORMAL, 0, NULL);
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap) {
+ return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
+ }
+ }
+ return FALSE;
+}
+FX_BOOL CGdiDisplayDriver::UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ FX_RECT bitmap_clip = *pClipRect;
+ if (dest_width < 0) {
+ dest_left += dest_width;
+ }
+ if (dest_height < 0) {
+ dest_top += dest_height;
+ }
+ bitmap_clip.Offset(-dest_left, -dest_top);
+ CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, render_flags, &bitmap_clip);
+ if (pStretched == NULL) {
+ return TRUE;
+ }
+ FX_RECT src_rect(0, 0, pStretched->GetWidth(), pStretched->GetHeight());
+ FX_BOOL ret = SetDIBits(pStretched, color, &src_rect, pClipRect->left, pClipRect->top, FXDIB_BLEND_NORMAL, alpha_flag, pIccTransform);
+ delete pStretched;
+ return ret;
+}
+FX_BOOL CGdiDisplayDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ ASSERT(pSource != NULL && pClipRect != NULL);
+ if (flags || dest_width > 10000 || dest_width < -10000 || dest_height > 10000 || dest_height < -10000)
+ return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
+ pClipRect, flags, alpha_flag, pIccTransform, blend_type);
+ if (pSource->IsAlphaMask()) {
+ FX_RECT image_rect;
+ image_rect.left = dest_width > 0 ? dest_left : dest_left + dest_width;
+ image_rect.right = dest_width > 0 ? dest_left + dest_width : dest_left;
+ image_rect.top = dest_height > 0 ? dest_top : dest_top + dest_height;
+ image_rect.bottom = dest_height > 0 ? dest_top + dest_height : dest_top;
+ FX_RECT clip_rect = image_rect;
+ clip_rect.Intersect(*pClipRect);
+ clip_rect.Offset(-image_rect.left, -image_rect.top);
+ int clip_width = clip_rect.Width(), clip_height = clip_rect.Height();
+ CFX_DIBitmap* pStretched = pSource->StretchTo(dest_width, dest_height, flags, &clip_rect);
+ if (pStretched == NULL) {
+ return TRUE;
+ }
+ CFX_DIBitmap background;
+ if (!background.Create(clip_width, clip_height, FXDIB_Rgb32) ||
+ !GetDIBits(&background, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, NULL) ||
+ !background.CompositeMask(0, 0, clip_width, clip_height, pStretched, color, 0, 0, FXDIB_BLEND_NORMAL, NULL, FALSE, alpha_flag, pIccTransform)) {
+ delete pStretched;
+ return FALSE;
+ }
+ FX_RECT src_rect(0, 0, clip_width, clip_height);
+ FX_BOOL ret = SetDIBits(&background, 0, &src_rect, image_rect.left + clip_rect.left, image_rect.top + clip_rect.top, FXDIB_BLEND_NORMAL, 0, NULL);
+ delete pStretched;
+ return ret;
+ } else {
+ if (pSource->HasAlpha()) {
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ if (pPlatform->m_GdiplusExt.IsAvailable() && pIccTransform == NULL && !pSource->IsCmykImage()) {
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ return pPlatform->m_GdiplusExt.StretchDIBits(m_hDC, pBitmap, dest_left, dest_top, dest_width, dest_height, pClipRect, flags);
+ }
+ return UseFoxitStretchEngine(pSource, color, dest_left, dest_top, dest_width, dest_height,
+ pClipRect, flags, alpha_flag, pIccTransform, blend_type);
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap) {
+ return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform);
+ }
+ }
+ return FALSE;
+}
+#define GET_PS_FEATURESETTING 4121
+#define FEATURESETTING_PSLEVEL 2
+int GetPSLevel(HDC hDC)
+{
+ int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
+ if (device_type != DT_RASPRINTER) {
+ return 0;
+ }
+ FX_DWORD esc = GET_PS_FEATURESETTING;
+ if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
+ int param = FEATURESETTING_PSLEVEL;
+ if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
+ return param;
+ }
+ }
+ esc = POSTSCRIPT_IDENTIFY;
+ if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL) == 0) {
+ esc = POSTSCRIPT_DATA;
+ if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
+ return 2;
+ }
+ return 0;
+ }
+ esc = PSIDENT_GDICENTRIC;
+ if (ExtEscape(hDC, POSTSCRIPT_IDENTIFY, sizeof(FX_DWORD), (char*)&esc, 0, NULL) <= 0) {
+ return 2;
+ }
+ esc = GET_PS_FEATURESETTING;
+ if (ExtEscape(hDC, QUERYESCSUPPORT, sizeof esc, (char*)&esc, 0, NULL)) {
+ int param = FEATURESETTING_PSLEVEL;
+ if (ExtEscape(hDC, GET_PS_FEATURESETTING, sizeof(int), (char*)&param, sizeof(int), (char*)&param) > 0) {
+ return param;
+ }
+ }
+ return 2;
+}
+int CFX_WindowsDevice::m_psLevel = 2;
+CFX_WindowsDevice::CFX_WindowsDevice(HDC hDC, FX_BOOL bCmykOutput, FX_BOOL bForcePSOutput, int psLevel)
+{
+ m_bForcePSOutput = bForcePSOutput;
+ m_psLevel = psLevel;
+ if (bForcePSOutput) {
+ IFX_RenderDeviceDriver* pDriver = FX_NEW CPSPrinterDriver;
+ if (!pDriver) {
+ return;
+ }
+ ((CPSPrinterDriver*)pDriver)->Init(hDC, psLevel, bCmykOutput);
+ SetDeviceDriver(pDriver);
+ return;
+ }
+ SetDeviceDriver(CreateDriver(hDC, bCmykOutput));
+}
+HDC CFX_WindowsDevice::GetDC() const
+{
+ IFX_RenderDeviceDriver *pRDD = GetDeviceDriver();
+ if (!pRDD) {
+ return NULL;
+ }
+ return (HDC)pRDD->GetPlatformSurface();
+}
+IFX_RenderDeviceDriver* CFX_WindowsDevice::CreateDriver(HDC hDC, FX_BOOL bCmykOutput)
+{
+ int device_type = ::GetDeviceCaps(hDC, TECHNOLOGY);
+ int obj_type = ::GetObjectType(hDC);
+ int device_class;
+ if (device_type == DT_RASPRINTER || device_type == DT_PLOTTER || obj_type == OBJ_ENHMETADC) {
+ device_class = FXDC_PRINTER;
+ } else {
+ device_class = FXDC_DISPLAY;
+ }
+ return FX_NEW CGdiDisplayDriver(hDC);
+}
+CFX_WinBitmapDevice::CFX_WinBitmapDevice(int width, int height, FXDIB_Format format)
+{
+ BITMAPINFOHEADER bmih;
+ FXSYS_memset32(&bmih, 0, sizeof (BITMAPINFOHEADER));
+ bmih.biSize = sizeof(BITMAPINFOHEADER);
+ bmih.biBitCount = format & 0xff;
+ bmih.biHeight = -height;
+ bmih.biPlanes = 1;
+ bmih.biWidth = width;
+ FX_LPBYTE pBuffer;
+ m_hBitmap = CreateDIBSection(NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (FX_LPVOID*)&pBuffer, NULL, 0);
+ if (m_hBitmap == NULL) {
+ return;
+ }
+ CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
+ if (!pBitmap) {
+ return;
+ }
+ pBitmap->Create(width, height, format, pBuffer);
+ SetBitmap(pBitmap);
+ m_hDC = ::CreateCompatibleDC(NULL);
+ m_hOldBitmap = (HBITMAP)SelectObject(m_hDC, m_hBitmap);
+ IFX_RenderDeviceDriver* pDriver = FX_NEW CGdiDisplayDriver(m_hDC);
+ if (!pDriver) {
+ return;
+ }
+ SetDeviceDriver(pDriver);
+}
+CFX_WinBitmapDevice::~CFX_WinBitmapDevice()
+{
+ if (m_hDC) {
+ SelectObject(m_hDC, m_hOldBitmap);
+ DeleteDC(m_hDC);
+ }
+ if (m_hBitmap) {
+ DeleteObject(m_hBitmap);
+ }
+ delete GetBitmap();
+}
+#endif
diff --git a/core/src/fxge/win32/fx_win32_dib.cpp b/core/src/fxge/win32/fx_win32_dib.cpp
index a9cf78eac3..0093d5e41b 100644
--- a/core/src/fxge/win32/fx_win32_dib.cpp
+++ b/core/src/fxge/win32/fx_win32_dib.cpp
@@ -1,310 +1,310 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include <windows.h>
-#include "../../../include/fxge/fx_ge_win32.h"
-#include "win32_int.h"
-CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap)
-{
- CFX_ByteString result;
- int len = sizeof (BITMAPINFOHEADER);
- if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) {
- len += sizeof (DWORD) * (int)(1 << pBitmap->GetBPP());
- }
- BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len);
- FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
- pbmih->biSize = sizeof(BITMAPINFOHEADER);
- pbmih->biBitCount = pBitmap->GetBPP();
- pbmih->biCompression = BI_RGB;
- pbmih->biHeight = -(int)pBitmap->GetHeight();
- pbmih->biPlanes = 1;
- pbmih->biWidth = pBitmap->GetWidth();
- if (pBitmap->GetBPP() == 8) {
- FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
- if (pBitmap->GetPalette() == NULL) {
- for (int i = 0; i < 256; i ++) {
- pPalette[i] = i * 0x010101;
- }
- } else {
- for (int i = 0; i < 256; i ++) {
- pPalette[i] = pBitmap->GetPalette()[i];
- }
- }
- }
- if (pBitmap->GetBPP() == 1) {
- FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
- if (pBitmap->GetPalette() == NULL) {
- pPalette[0] = 0;
- pPalette[1] = 0xffffff;
- } else {
- pPalette[0] = pBitmap->GetPalette()[0];
- pPalette[1] = pBitmap->GetPalette()[1];
- }
- }
- result.ReleaseBuffer(len);
- return result;
-}
-CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha)
-{
- int width = pbmi->bmiHeader.biWidth;
- int height = pbmi->bmiHeader.biHeight;
- BOOL bBottomUp = TRUE;
- if (height < 0) {
- height = -height;
- bBottomUp = FALSE;
- }
- int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
- CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
- if (!pBitmap) {
- return NULL;
- }
- FXDIB_Format format = bAlpha ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) : (FXDIB_Format)pbmi->bmiHeader.biBitCount;
- FX_BOOL ret = pBitmap->Create(width, height, format);
- if (!ret) {
- delete pBitmap;
- return NULL;
- }
- FXSYS_memcpy32(pBitmap->GetBuffer(), pData, pitch * height);
- if (bBottomUp) {
- FX_LPBYTE temp_buf = FX_Alloc(FX_BYTE, pitch);
- if (!temp_buf) {
- if (pBitmap) {
- delete pBitmap;
- }
- return NULL;
- }
- int top = 0, bottom = height - 1;
- while (top < bottom) {
- FXSYS_memcpy32(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch);
- FXSYS_memcpy32(pBitmap->GetBuffer() + top * pitch, pBitmap->GetBuffer() + bottom * pitch, pitch);
- FXSYS_memcpy32(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch);
- top ++;
- bottom --;
- }
- FX_Free(temp_buf);
- temp_buf = NULL;
- }
- if (pbmi->bmiHeader.biBitCount == 1) {
- for (int i = 0; i < 2; i ++) {
- pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
- }
- } else if (pbmi->bmiHeader.biBitCount == 8) {
- for (int i = 0; i < 256; i ++) {
- pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
- }
- }
- return pBitmap;
-}
-CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData)
-{
- return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE);
-}
-HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC)
-{
- CFX_ByteString info = GetBitmapInfo(pBitmap);
- HBITMAP hBitmap = NULL;
- hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)(FX_LPCSTR)info, CBM_INIT,
- pBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
- return hBitmap;
-}
-void GetBitmapSize(HBITMAP hBitmap, int& w, int& h)
-{
- BITMAP bmp;
- GetObject(hBitmap, sizeof bmp, &bmp);
- w = bmp.bmWidth;
- h = bmp.bmHeight;
-}
-CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(FX_LPCWSTR filename)
-{
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- if (pPlatform->m_GdiplusExt.IsAvailable()) {
- WINDIB_Open_Args_ args;
- args.flags = WINDIB_OPEN_PATHNAME;
- args.path_name = filename;
- return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
- }
- HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
- if (hBitmap == NULL) {
- return NULL;
- }
- HDC hDC = CreateCompatibleDC(NULL);
- int width, height;
- GetBitmapSize(hBitmap, width, height);
- CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
- if (!pDIBitmap) {
- DeleteDC(hDC);
- return NULL;
- }
- if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
- delete pDIBitmap;
- DeleteDC(hDC);
- return NULL;
- }
- CFX_ByteString info = GetBitmapInfo(pDIBitmap);
- int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
- if (!ret) {
- if (pDIBitmap) {
- delete pDIBitmap;
- }
- pDIBitmap = NULL;
- }
- DeleteDC(hDC);
- return pDIBitmap;
-}
-CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args)
-{
- CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
- if (pPlatform->m_GdiplusExt.IsAvailable()) {
- return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
- } else if (args.flags == WINDIB_OPEN_MEMORY) {
- return NULL;
- }
- HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
- if (hBitmap == NULL) {
- return NULL;
- }
- HDC hDC = CreateCompatibleDC(NULL);
- int width, height;
- GetBitmapSize(hBitmap, width, height);
- CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
- if (!pDIBitmap) {
- DeleteDC(hDC);
- return NULL;
- }
- if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
- delete pDIBitmap;
- DeleteDC(hDC);
- return NULL;
- }
- CFX_ByteString info = GetBitmapInfo(pDIBitmap);
- int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
- if (!ret) {
- if (pDIBitmap) {
- delete pDIBitmap;
- }
- pDIBitmap = NULL;
- }
- DeleteDC(hDC);
- return pDIBitmap;
-}
-CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette, FX_DWORD palsize)
-{
- FX_BOOL bCreatedDC = hDC == NULL;
- if (hDC == NULL) {
- hDC = CreateCompatibleDC(NULL);
- }
- BITMAPINFOHEADER bmih;
- FXSYS_memset32(&bmih, 0, sizeof bmih);
- bmih.biSize = sizeof bmih;
- GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
- int width = bmih.biWidth;
- int height = abs(bmih.biHeight);
- bmih.biHeight = -height;
- bmih.biCompression = BI_RGB;
- CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
- if (!pDIBitmap) {
- return NULL;
- }
- int ret = 0;
- if (bmih.biBitCount == 1 || bmih.biBitCount == 8) {
- int size = sizeof (BITMAPINFOHEADER) + 8;
- if (bmih.biBitCount == 8) {
- size += sizeof (FX_DWORD) * 254;
- }
- BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(FX_BYTE, size);
- if (!pbmih) {
- delete pDIBitmap;
- if (bCreatedDC) {
- DeleteDC(hDC);
- }
- return NULL;
- }
- FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
- pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pbmih->bmiHeader.biBitCount = bmih.biBitCount;
- pbmih->bmiHeader.biCompression = BI_RGB;
- pbmih->bmiHeader.biHeight = -height;
- pbmih->bmiHeader.biPlanes = 1;
- pbmih->bmiHeader.biWidth = bmih.biWidth;
- if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) {
- delete pDIBitmap;
- FX_Free(pbmih);
- if (bCreatedDC) {
- DeleteDC(hDC);
- }
- return NULL;
- }
- ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)pbmih, DIB_RGB_COLORS);
- FX_Free(pbmih);
- pbmih = NULL;
- pDIBitmap->CopyPalette(pPalette, palsize);
- } else {
- if (bmih.biBitCount <= 24) {
- bmih.biBitCount = 24;
- } else {
- bmih.biBitCount = 32;
- }
- if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) {
- delete pDIBitmap;
- if (bCreatedDC) {
- DeleteDC(hDC);
- }
- return NULL;
- }
- ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
- if (ret != 0 && bmih.biBitCount == 32) {
- int pitch = pDIBitmap->GetPitch();
- for (int row = 0; row < height; row ++) {
- FX_BYTE* dest_scan = (FX_BYTE*)(pDIBitmap->GetBuffer() + row * pitch);
- for (int col = 0; col < width; col++) {
- dest_scan[3] = 255;
- dest_scan += 4;
- }
- }
- }
- }
- if (ret == 0) {
- if (pDIBitmap) {
- delete pDIBitmap;
- }
- pDIBitmap = NULL;
- }
- if (bCreatedDC) {
- DeleteDC(hDC);
- }
- return pDIBitmap;
-}
-CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height)
-{
- Create(width, height, FXDIB_Rgb, (FX_LPBYTE)1);
- BITMAPINFOHEADER bmih;
- FXSYS_memset32(&bmih, 0, sizeof bmih);
- bmih.biSize = sizeof bmih;
- bmih.biBitCount = 24;
- bmih.biHeight = -height;
- bmih.biPlanes = 1;
- bmih.biWidth = width;
- m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOID*)&m_pBuffer, NULL, 0);
- m_hMemDC = CreateCompatibleDC(hDC);
- m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
-}
-CFX_WindowsDIB::~CFX_WindowsDIB()
-{
- SelectObject(m_hMemDC, m_hOldBitmap);
- DeleteDC(m_hMemDC);
- DeleteObject(m_hBitmap);
-}
-void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top)
-{
- ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY);
-}
-void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top)
-{
- ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY);
-}
-#endif
+// 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 "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include <windows.h>
+#include "../../../include/fxge/fx_ge_win32.h"
+#include "win32_int.h"
+CFX_ByteString CFX_WindowsDIB::GetBitmapInfo(const CFX_DIBitmap* pBitmap)
+{
+ CFX_ByteString result;
+ int len = sizeof (BITMAPINFOHEADER);
+ if (pBitmap->GetBPP() == 1 || pBitmap->GetBPP() == 8) {
+ len += sizeof (DWORD) * (int)(1 << pBitmap->GetBPP());
+ }
+ BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)result.GetBuffer(len);
+ FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
+ pbmih->biSize = sizeof(BITMAPINFOHEADER);
+ pbmih->biBitCount = pBitmap->GetBPP();
+ pbmih->biCompression = BI_RGB;
+ pbmih->biHeight = -(int)pBitmap->GetHeight();
+ pbmih->biPlanes = 1;
+ pbmih->biWidth = pBitmap->GetWidth();
+ if (pBitmap->GetBPP() == 8) {
+ FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
+ if (pBitmap->GetPalette() == NULL) {
+ for (int i = 0; i < 256; i ++) {
+ pPalette[i] = i * 0x010101;
+ }
+ } else {
+ for (int i = 0; i < 256; i ++) {
+ pPalette[i] = pBitmap->GetPalette()[i];
+ }
+ }
+ }
+ if (pBitmap->GetBPP() == 1) {
+ FX_DWORD* pPalette = (FX_DWORD*)(pbmih + 1);
+ if (pBitmap->GetPalette() == NULL) {
+ pPalette[0] = 0;
+ pPalette[1] = 0xffffff;
+ } else {
+ pPalette[0] = pBitmap->GetPalette()[0];
+ pPalette[1] = pBitmap->GetPalette()[1];
+ }
+ }
+ result.ReleaseBuffer(len);
+ return result;
+}
+CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha)
+{
+ int width = pbmi->bmiHeader.biWidth;
+ int height = pbmi->bmiHeader.biHeight;
+ BOOL bBottomUp = TRUE;
+ if (height < 0) {
+ height = -height;
+ bBottomUp = FALSE;
+ }
+ int pitch = (width * pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
+ CFX_DIBitmap* pBitmap = FX_NEW CFX_DIBitmap;
+ if (!pBitmap) {
+ return NULL;
+ }
+ FXDIB_Format format = bAlpha ? (FXDIB_Format)(pbmi->bmiHeader.biBitCount + 0x200) : (FXDIB_Format)pbmi->bmiHeader.biBitCount;
+ FX_BOOL ret = pBitmap->Create(width, height, format);
+ if (!ret) {
+ delete pBitmap;
+ return NULL;
+ }
+ FXSYS_memcpy32(pBitmap->GetBuffer(), pData, pitch * height);
+ if (bBottomUp) {
+ FX_LPBYTE temp_buf = FX_Alloc(FX_BYTE, pitch);
+ if (!temp_buf) {
+ if (pBitmap) {
+ delete pBitmap;
+ }
+ return NULL;
+ }
+ int top = 0, bottom = height - 1;
+ while (top < bottom) {
+ FXSYS_memcpy32(temp_buf, pBitmap->GetBuffer() + top * pitch, pitch);
+ FXSYS_memcpy32(pBitmap->GetBuffer() + top * pitch, pBitmap->GetBuffer() + bottom * pitch, pitch);
+ FXSYS_memcpy32(pBitmap->GetBuffer() + bottom * pitch, temp_buf, pitch);
+ top ++;
+ bottom --;
+ }
+ FX_Free(temp_buf);
+ temp_buf = NULL;
+ }
+ if (pbmi->bmiHeader.biBitCount == 1) {
+ for (int i = 0; i < 2; i ++) {
+ pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
+ }
+ } else if (pbmi->bmiHeader.biBitCount == 8) {
+ for (int i = 0; i < 256; i ++) {
+ pBitmap->SetPaletteEntry(i, ((FX_DWORD*)pbmi->bmiColors)[i] | 0xff000000);
+ }
+ }
+ return pBitmap;
+}
+CFX_DIBitmap* CFX_WindowsDIB::LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData)
+{
+ return _FX_WindowsDIB_LoadFromBuf(pbmi, pData, FALSE);
+}
+HBITMAP CFX_WindowsDIB::GetDDBitmap(const CFX_DIBitmap* pBitmap, HDC hDC)
+{
+ CFX_ByteString info = GetBitmapInfo(pBitmap);
+ HBITMAP hBitmap = NULL;
+ hBitmap = CreateDIBitmap(hDC, (BITMAPINFOHEADER*)(FX_LPCSTR)info, CBM_INIT,
+ pBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
+ return hBitmap;
+}
+void GetBitmapSize(HBITMAP hBitmap, int& w, int& h)
+{
+ BITMAP bmp;
+ GetObject(hBitmap, sizeof bmp, &bmp);
+ w = bmp.bmWidth;
+ h = bmp.bmHeight;
+}
+CFX_DIBitmap* CFX_WindowsDIB::LoadFromFile(FX_LPCWSTR filename)
+{
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ if (pPlatform->m_GdiplusExt.IsAvailable()) {
+ WINDIB_Open_Args_ args;
+ args.flags = WINDIB_OPEN_PATHNAME;
+ args.path_name = filename;
+ return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
+ }
+ HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)filename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+ if (hBitmap == NULL) {
+ return NULL;
+ }
+ HDC hDC = CreateCompatibleDC(NULL);
+ int width, height;
+ GetBitmapSize(hBitmap, width, height);
+ CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
+ if (!pDIBitmap) {
+ DeleteDC(hDC);
+ return NULL;
+ }
+ if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
+ delete pDIBitmap;
+ DeleteDC(hDC);
+ return NULL;
+ }
+ CFX_ByteString info = GetBitmapInfo(pDIBitmap);
+ int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
+ if (!ret) {
+ if (pDIBitmap) {
+ delete pDIBitmap;
+ }
+ pDIBitmap = NULL;
+ }
+ DeleteDC(hDC);
+ return pDIBitmap;
+}
+CFX_DIBitmap* CFX_WindowsDIB::LoadDIBitmap(WINDIB_Open_Args_ args)
+{
+ CWin32Platform* pPlatform = (CWin32Platform*)CFX_GEModule::Get()->GetPlatformData();
+ if (pPlatform->m_GdiplusExt.IsAvailable()) {
+ return pPlatform->m_GdiplusExt.LoadDIBitmap(args);
+ } else if (args.flags == WINDIB_OPEN_MEMORY) {
+ return NULL;
+ }
+ HBITMAP hBitmap = (HBITMAP)LoadImageW(NULL, (wchar_t*)args.path_name, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
+ if (hBitmap == NULL) {
+ return NULL;
+ }
+ HDC hDC = CreateCompatibleDC(NULL);
+ int width, height;
+ GetBitmapSize(hBitmap, width, height);
+ CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
+ if (!pDIBitmap) {
+ DeleteDC(hDC);
+ return NULL;
+ }
+ if (!pDIBitmap->Create(width, height, FXDIB_Rgb)) {
+ delete pDIBitmap;
+ DeleteDC(hDC);
+ return NULL;
+ }
+ CFX_ByteString info = GetBitmapInfo(pDIBitmap);
+ int ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)(FX_LPCSTR)info, DIB_RGB_COLORS);
+ if (!ret) {
+ if (pDIBitmap) {
+ delete pDIBitmap;
+ }
+ pDIBitmap = NULL;
+ }
+ DeleteDC(hDC);
+ return pDIBitmap;
+}
+CFX_DIBitmap* CFX_WindowsDIB::LoadFromDDB(HDC hDC, HBITMAP hBitmap, FX_DWORD* pPalette, FX_DWORD palsize)
+{
+ FX_BOOL bCreatedDC = hDC == NULL;
+ if (hDC == NULL) {
+ hDC = CreateCompatibleDC(NULL);
+ }
+ BITMAPINFOHEADER bmih;
+ FXSYS_memset32(&bmih, 0, sizeof bmih);
+ bmih.biSize = sizeof bmih;
+ GetDIBits(hDC, hBitmap, 0, 0, NULL, (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
+ int width = bmih.biWidth;
+ int height = abs(bmih.biHeight);
+ bmih.biHeight = -height;
+ bmih.biCompression = BI_RGB;
+ CFX_DIBitmap* pDIBitmap = FX_NEW CFX_DIBitmap;
+ if (!pDIBitmap) {
+ return NULL;
+ }
+ int ret = 0;
+ if (bmih.biBitCount == 1 || bmih.biBitCount == 8) {
+ int size = sizeof (BITMAPINFOHEADER) + 8;
+ if (bmih.biBitCount == 8) {
+ size += sizeof (FX_DWORD) * 254;
+ }
+ BITMAPINFO* pbmih = (BITMAPINFO*)FX_Alloc(FX_BYTE, size);
+ if (!pbmih) {
+ delete pDIBitmap;
+ if (bCreatedDC) {
+ DeleteDC(hDC);
+ }
+ return NULL;
+ }
+ FXSYS_memset32(pbmih, 0, sizeof (BITMAPINFOHEADER));
+ pbmih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ pbmih->bmiHeader.biBitCount = bmih.biBitCount;
+ pbmih->bmiHeader.biCompression = BI_RGB;
+ pbmih->bmiHeader.biHeight = -height;
+ pbmih->bmiHeader.biPlanes = 1;
+ pbmih->bmiHeader.biWidth = bmih.biWidth;
+ if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 1 ? FXDIB_1bppRgb : FXDIB_8bppRgb)) {
+ delete pDIBitmap;
+ FX_Free(pbmih);
+ if (bCreatedDC) {
+ DeleteDC(hDC);
+ }
+ return NULL;
+ }
+ ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)pbmih, DIB_RGB_COLORS);
+ FX_Free(pbmih);
+ pbmih = NULL;
+ pDIBitmap->CopyPalette(pPalette, palsize);
+ } else {
+ if (bmih.biBitCount <= 24) {
+ bmih.biBitCount = 24;
+ } else {
+ bmih.biBitCount = 32;
+ }
+ if (!pDIBitmap->Create(bmih.biWidth, height, bmih.biBitCount == 24 ? FXDIB_Rgb : FXDIB_Rgb32)) {
+ delete pDIBitmap;
+ if (bCreatedDC) {
+ DeleteDC(hDC);
+ }
+ return NULL;
+ }
+ ret = GetDIBits(hDC, hBitmap, 0, height, pDIBitmap->GetBuffer(), (BITMAPINFO*)&bmih, DIB_RGB_COLORS);
+ if (ret != 0 && bmih.biBitCount == 32) {
+ int pitch = pDIBitmap->GetPitch();
+ for (int row = 0; row < height; row ++) {
+ FX_BYTE* dest_scan = (FX_BYTE*)(pDIBitmap->GetBuffer() + row * pitch);
+ for (int col = 0; col < width; col++) {
+ dest_scan[3] = 255;
+ dest_scan += 4;
+ }
+ }
+ }
+ }
+ if (ret == 0) {
+ if (pDIBitmap) {
+ delete pDIBitmap;
+ }
+ pDIBitmap = NULL;
+ }
+ if (bCreatedDC) {
+ DeleteDC(hDC);
+ }
+ return pDIBitmap;
+}
+CFX_WindowsDIB::CFX_WindowsDIB(HDC hDC, int width, int height)
+{
+ Create(width, height, FXDIB_Rgb, (FX_LPBYTE)1);
+ BITMAPINFOHEADER bmih;
+ FXSYS_memset32(&bmih, 0, sizeof bmih);
+ bmih.biSize = sizeof bmih;
+ bmih.biBitCount = 24;
+ bmih.biHeight = -height;
+ bmih.biPlanes = 1;
+ bmih.biWidth = width;
+ m_hBitmap = CreateDIBSection(hDC, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (LPVOID*)&m_pBuffer, NULL, 0);
+ m_hMemDC = CreateCompatibleDC(hDC);
+ m_hOldBitmap = (HBITMAP)SelectObject(m_hMemDC, m_hBitmap);
+}
+CFX_WindowsDIB::~CFX_WindowsDIB()
+{
+ SelectObject(m_hMemDC, m_hOldBitmap);
+ DeleteDC(m_hMemDC);
+ DeleteObject(m_hBitmap);
+}
+void CFX_WindowsDIB::LoadFromDevice(HDC hDC, int left, int top)
+{
+ ::BitBlt(m_hMemDC, 0, 0, m_Width, m_Height, hDC, left, top, SRCCOPY);
+}
+void CFX_WindowsDIB::SetToDevice(HDC hDC, int left, int top)
+{
+ ::BitBlt(hDC, left, top, m_Width, m_Height, m_hMemDC, 0, 0, SRCCOPY);
+}
+#endif
diff --git a/core/src/fxge/win32/fx_win32_dwrite.cpp b/core/src/fxge/win32/fx_win32_dwrite.cpp
index d4c962036e..2c275a88c8 100644
--- a/core/src/fxge/win32/fx_win32_dwrite.cpp
+++ b/core/src/fxge/win32/fx_win32_dwrite.cpp
@@ -1,480 +1,480 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include "../../../include/fxge/fx_ge_win32.h"
-#include "dwrite_int.h"
-#include "../Microsoft SDK/include/DWrite.h"
-typedef HRESULT (__stdcall *FuncType_DWriteCreateFactory)(__in DWRITE_FACTORY_TYPE, __in REFIID, __out IUnknown **);
-template <typename InterfaceType>
-inline void SafeRelease(InterfaceType** currentObject)
-{
- if (*currentObject != NULL) {
- (*currentObject)->Release();
- *currentObject = NULL;
- }
-}
-template <typename InterfaceType>
-inline InterfaceType* SafeAcquire(InterfaceType* newObject)
-{
- if (newObject != NULL) {
- newObject->AddRef();
- }
- return newObject;
-}
-class CDwFontFileStream : public IDWriteFontFileStream, public CFX_Object
-{
-public:
- explicit CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize);
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
- virtual ULONG STDMETHODCALLTYPE AddRef();
- virtual ULONG STDMETHODCALLTYPE Release();
- virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, UINT64 fragmentSize, OUT void** fragmentContext);
- virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext);
- virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize);
- virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime);
- bool IsInitialized()
- {
- return resourcePtr_ != NULL;
- }
-private:
- ULONG refCount_;
- void const* resourcePtr_;
- DWORD resourceSize_;
-};
-class CDwFontFileLoader : public IDWriteFontFileLoader, public CFX_Object
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
- virtual ULONG STDMETHODCALLTYPE AddRef();
- virtual ULONG STDMETHODCALLTYPE Release();
- virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, OUT IDWriteFontFileStream** fontFileStream);
-
- static IDWriteFontFileLoader* GetLoader()
- {
- if (instance_ == NULL) {
- instance_ = FX_NEW CDwFontFileLoader();
- return instance_;
- }
- return instance_;
- }
- static bool IsLoaderInitialized()
- {
- return instance_ != NULL;
- }
-private:
- CDwFontFileLoader();
- ULONG refCount_;
- static IDWriteFontFileLoader* instance_;
-};
-class CDwFontContext : public CFX_Object
-{
-public:
- CDwFontContext(IDWriteFactory* dwriteFactory);
- ~CDwFontContext();
- HRESULT Initialize();
-private:
- CDwFontContext(CDwFontContext const&);
- void operator=(CDwFontContext const&);
- HRESULT hr_;
- IDWriteFactory* dwriteFactory_;
-};
-class CDwGdiTextRenderer : public CFX_Object
-{
-public:
- CDwGdiTextRenderer(
- CFX_DIBitmap* pBitmap,
- IDWriteBitmapRenderTarget* bitmapRenderTarget,
- IDWriteRenderingParams* renderingParams
- );
- CDwGdiTextRenderer::~CDwGdiTextRenderer();
- HRESULT STDMETHODCALLTYPE DrawGlyphRun(
- const FX_RECT& text_bbox,
- __in_opt CFX_ClipRgn* pClipRgn,
- __in_opt DWRITE_MATRIX const* pMatrix,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- DWRITE_MEASURING_MODE measuringMode,
- __in DWRITE_GLYPH_RUN const* glyphRun,
- const COLORREF& textColor
- );
-private:
- CFX_DIBitmap* pBitmap_;
- IDWriteBitmapRenderTarget* pRenderTarget_;
- IDWriteRenderingParams* pRenderingParams_;
-};
-CDWriteExt::CDWriteExt()
-{
- m_hModule = NULL;
- m_pDWriteFactory = NULL;
- m_pDwFontContext = NULL;
- m_pDwTextRenderer = NULL;
-}
-void CDWriteExt::Load()
-{
-}
-void CDWriteExt::Unload()
-{
- if (m_pDwFontContext) {
- delete (CDwFontContext*)m_pDwFontContext;
- m_pDwFontContext = NULL;
- }
- SafeRelease((IDWriteFactory**)&m_pDWriteFactory);
-}
-CDWriteExt::~CDWriteExt()
-{
- Unload();
-}
-LPVOID CDWriteExt::DwCreateFontFaceFromStream(FX_LPBYTE pData, FX_DWORD size, int simulation_style)
-{
- IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
- IDWriteFontFile* pDwFontFile = NULL;
- IDWriteFontFace* pDwFontFace = NULL;
- BOOL isSupportedFontType = FALSE;
- DWRITE_FONT_FILE_TYPE fontFileType;
- DWRITE_FONT_FACE_TYPE fontFaceType;
- UINT32 numberOfFaces;
- DWRITE_FONT_SIMULATIONS fontStyle = (DWRITE_FONT_SIMULATIONS)(simulation_style & 3);
- HRESULT hr = S_OK;
- hr = pDwFactory->CreateCustomFontFileReference(
- (void const*)pData,
- (UINT32)size,
- CDwFontFileLoader::GetLoader(),
- &pDwFontFile
- );
- if (FAILED(hr)) {
- goto failed;
- }
- hr = pDwFontFile->Analyze(
- &isSupportedFontType,
- &fontFileType,
- &fontFaceType,
- &numberOfFaces
- );
- if (FAILED(hr) || !isSupportedFontType || fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) {
- goto failed;
- }
- hr = pDwFactory->CreateFontFace(
- fontFaceType,
- 1,
- &pDwFontFile,
- 0,
- fontStyle,
- &pDwFontFace
- );
- if (FAILED(hr)) {
- goto failed;
- }
- SafeRelease(&pDwFontFile);
- return pDwFontFace;
-failed:
- SafeRelease(&pDwFontFile);
- return NULL;
-}
-FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, void** renderTarget)
-{
- if (pBitmap->GetFormat() > FXDIB_Argb) {
- return FALSE;
- }
- IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
- IDWriteGdiInterop* pGdiInterop = NULL;
- IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL;
- IDWriteRenderingParams* pRenderingParams = NULL;
- HRESULT hr = S_OK;
- hr = pDwFactory->GetGdiInterop(&pGdiInterop);
- if (FAILED(hr)) {
- goto failed;
- }
- hr = pGdiInterop->CreateBitmapRenderTarget(NULL, pBitmap->GetWidth(), pBitmap->GetHeight(),
- &pBitmapRenderTarget);
- if (FAILED(hr)) {
- goto failed;
- }
- hr = pDwFactory->CreateCustomRenderingParams(
- 1.0f,
- 0.0f,
- 1.0f,
- DWRITE_PIXEL_GEOMETRY_RGB,
- DWRITE_RENDERING_MODE_DEFAULT,
- &pRenderingParams
- );
- if (FAILED(hr)) {
- goto failed;
- }
- hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f);
- if (FAILED(hr)) {
- goto failed;
- }
- *(CDwGdiTextRenderer**)renderTarget = FX_NEW CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams);
- if (*(CDwGdiTextRenderer**)renderTarget == NULL) {
- goto failed;
- }
- SafeRelease(&pGdiInterop);
- SafeRelease(&pBitmapRenderTarget);
- SafeRelease(&pRenderingParams);
- return TRUE;
-failed:
- SafeRelease(&pGdiInterop);
- SafeRelease(&pBitmapRenderTarget);
- SafeRelease(&pRenderingParams);
- return FALSE;
-}
-FX_BOOL CDWriteExt::DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix,
- void *font, FX_FLOAT font_size, FX_ARGB text_color,
- int glyph_count, unsigned short* glyph_indices,
- FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY,
- void* glyph_offsets,
- FX_FLOAT* glyph_advances)
-{
- if (renderTarget == NULL) {
- return TRUE;
- }
- CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget;
- DWRITE_MATRIX transform;
- DWRITE_GLYPH_RUN glyphRun;
- HRESULT hr = S_OK;
- if (pMatrix) {
- transform.m11 = pMatrix->a;
- transform.m12 = pMatrix->b;
- transform.m21 = pMatrix->c;
- transform.m22 = pMatrix->d;
- transform.dx = pMatrix->e;
- transform.dy = pMatrix->f;
- }
- glyphRun.fontFace = (IDWriteFontFace*)font;
- glyphRun.fontEmSize = font_size;
- glyphRun.glyphCount = glyph_count;
- glyphRun.glyphIndices = glyph_indices;
- glyphRun.glyphAdvances = glyph_advances;
- glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets;
- glyphRun.isSideways = FALSE;
- glyphRun.bidiLevel = 0;
- hr = pTextRenderer->DrawGlyphRun(
- stringRect,
- pClipRgn,
- pMatrix ? &transform : NULL,
- baselineOriginX, baselineOriginY,
- DWRITE_MEASURING_MODE_NATURAL,
- &glyphRun,
- RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color))
- );
- return SUCCEEDED(hr) ? TRUE : FALSE;
-}
-void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget)
-{
- if (renderTarget) {
- delete (CDwGdiTextRenderer*)renderTarget;
- }
-}
-void CDWriteExt::DwDeleteFont(void* pFont)
-{
- if (pFont) {
- SafeRelease((IDWriteFontFace**)&pFont);
- }
-}
-CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize)
-{
- refCount_ = 0;
- resourcePtr_ = fontFileReferenceKey;
- resourceSize_ = fontFileReferenceKeySize;
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, void** ppvObject)
-{
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
- *ppvObject = this;
- AddRef();
- return S_OK;
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
-}
-ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef()
-{
- return InterlockedIncrement((long*)(&refCount_));
-}
-ULONG STDMETHODCALLTYPE CDwFontFileStream::Release()
-{
- ULONG newCount = InterlockedDecrement((long*)(&refCount_));
- if (newCount == 0) {
- delete this;
- }
- return newCount;
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileStream::ReadFileFragment(
- void const** fragmentStart,
- UINT64 fileOffset,
- UINT64 fragmentSize,
- OUT void** fragmentContext
-)
-{
- if (fileOffset <= resourceSize_ &&
- fragmentSize <= resourceSize_ - fileOffset) {
- *fragmentStart = static_cast<FX_BYTE const*>(resourcePtr_) + static_cast<size_t>(fileOffset);
- *fragmentContext = NULL;
- return S_OK;
- } else {
- *fragmentStart = NULL;
- *fragmentContext = NULL;
- return E_FAIL;
- }
-}
-void STDMETHODCALLTYPE CDwFontFileStream::ReleaseFileFragment(void* fragmentContext)
-{
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize)
-{
- *fileSize = resourceSize_;
- return S_OK;
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime)
-{
- *lastWriteTime = 0;
- return E_NOTIMPL;
-}
-IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL;
-CDwFontFileLoader::CDwFontFileLoader() :
- refCount_(0)
-{
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, void** ppvObject)
-{
- if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
- *ppvObject = this;
- AddRef();
- return S_OK;
- } else {
- *ppvObject = NULL;
- return E_NOINTERFACE;
- }
-}
-ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef()
-{
- return InterlockedIncrement((long*)(&refCount_));
-}
-ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release()
-{
- ULONG newCount = InterlockedDecrement((long*)(&refCount_));
- if (newCount == 0) {
- instance_ = NULL;
- delete this;
- }
- return newCount;
-}
-HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey(
- void const* fontFileReferenceKey,
- UINT32 fontFileReferenceKeySize,
- OUT IDWriteFontFileStream** fontFileStream
-)
-{
- *fontFileStream = NULL;
- CDwFontFileStream* stream = FX_NEW CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize);
- if (stream == NULL) {
- return E_OUTOFMEMORY;
- }
- if (!stream->IsInitialized()) {
- delete stream;
- return E_FAIL;
- }
- *fontFileStream = SafeAcquire(stream);
- return S_OK;
-}
-CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) :
- hr_(S_FALSE),
- dwriteFactory_(SafeAcquire(dwriteFactory))
-{
-}
-CDwFontContext::~CDwFontContext()
-{
- if(dwriteFactory_ && hr_ == S_OK) {
- dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader());
- }
- SafeRelease(&dwriteFactory_);
-}
-HRESULT CDwFontContext::Initialize()
-{
- if (hr_ == S_FALSE) {
- return hr_ = dwriteFactory_->RegisterFontFileLoader(CDwFontFileLoader::GetLoader());
- }
- return hr_;
-}
-CDwGdiTextRenderer::CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, IDWriteBitmapRenderTarget* bitmapRenderTarget, IDWriteRenderingParams* renderingParams):
- pBitmap_(pBitmap),
- pRenderTarget_(SafeAcquire(bitmapRenderTarget)),
- pRenderingParams_(SafeAcquire(renderingParams))
-{
-}
-CDwGdiTextRenderer::~CDwGdiTextRenderer()
-{
- SafeRelease(&pRenderTarget_);
- SafeRelease(&pRenderingParams_);
-}
-STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun(
- const FX_RECT& text_bbox,
- __in_opt CFX_ClipRgn* pClipRgn,
- __in_opt DWRITE_MATRIX const* pMatrix,
- FLOAT baselineOriginX,
- FLOAT baselineOriginY,
- DWRITE_MEASURING_MODE measuringMode,
- __in DWRITE_GLYPH_RUN const* glyphRun,
- const COLORREF& textColor
-)
-{
- HRESULT hr = S_OK;
- if (pMatrix) {
- hr = pRenderTarget_->SetCurrentTransform(pMatrix);
- if (FAILED(hr)) {
- return hr;
- }
- }
- HDC hDC = pRenderTarget_->GetMemoryDC();
- HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP);
- BITMAP bitmap;
- GetObject(hBitmap, sizeof bitmap, &bitmap);
- CFX_DIBitmap dib;
- dib.Create(
- bitmap.bmWidth,
- bitmap.bmHeight,
- bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32,
- (FX_LPBYTE)bitmap.bmBits
- );
- dib.CompositeBitmap(
- text_bbox.left,
- text_bbox.top,
- text_bbox.Width(),
- text_bbox.Height(),
- pBitmap_,
- text_bbox.left,
- text_bbox.top,
- FXDIB_BLEND_NORMAL,
- NULL
- );
- hr = pRenderTarget_->DrawGlyphRun(
- baselineOriginX,
- baselineOriginY,
- measuringMode,
- glyphRun,
- pRenderingParams_,
- textColor
- );
- if (FAILED(hr)) {
- return hr;
- }
- pBitmap_->CompositeBitmap(
- text_bbox.left,
- text_bbox.top,
- text_bbox.Width(),
- text_bbox.Height(),
- &dib,
- text_bbox.left,
- text_bbox.top,
- FXDIB_BLEND_NORMAL,
- pClipRgn
- );
- return hr;
-}
-#endif
+// 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 "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include "../../../include/fxge/fx_ge_win32.h"
+#include "dwrite_int.h"
+#include "../Microsoft SDK/include/DWrite.h"
+typedef HRESULT (__stdcall *FuncType_DWriteCreateFactory)(__in DWRITE_FACTORY_TYPE, __in REFIID, __out IUnknown **);
+template <typename InterfaceType>
+inline void SafeRelease(InterfaceType** currentObject)
+{
+ if (*currentObject != NULL) {
+ (*currentObject)->Release();
+ *currentObject = NULL;
+ }
+}
+template <typename InterfaceType>
+inline InterfaceType* SafeAcquire(InterfaceType* newObject)
+{
+ if (newObject != NULL) {
+ newObject->AddRef();
+ }
+ return newObject;
+}
+class CDwFontFileStream : public IDWriteFontFileStream, public CFX_Object
+{
+public:
+ explicit CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize);
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual ULONG STDMETHODCALLTYPE Release();
+ virtual HRESULT STDMETHODCALLTYPE ReadFileFragment(void const** fragmentStart, UINT64 fileOffset, UINT64 fragmentSize, OUT void** fragmentContext);
+ virtual void STDMETHODCALLTYPE ReleaseFileFragment(void* fragmentContext);
+ virtual HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64* fileSize);
+ virtual HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64* lastWriteTime);
+ bool IsInitialized()
+ {
+ return resourcePtr_ != NULL;
+ }
+private:
+ ULONG refCount_;
+ void const* resourcePtr_;
+ DWORD resourceSize_;
+};
+class CDwFontFileLoader : public IDWriteFontFileLoader, public CFX_Object
+{
+public:
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef();
+ virtual ULONG STDMETHODCALLTYPE Release();
+ virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, OUT IDWriteFontFileStream** fontFileStream);
+
+ static IDWriteFontFileLoader* GetLoader()
+ {
+ if (instance_ == NULL) {
+ instance_ = FX_NEW CDwFontFileLoader();
+ return instance_;
+ }
+ return instance_;
+ }
+ static bool IsLoaderInitialized()
+ {
+ return instance_ != NULL;
+ }
+private:
+ CDwFontFileLoader();
+ ULONG refCount_;
+ static IDWriteFontFileLoader* instance_;
+};
+class CDwFontContext : public CFX_Object
+{
+public:
+ CDwFontContext(IDWriteFactory* dwriteFactory);
+ ~CDwFontContext();
+ HRESULT Initialize();
+private:
+ CDwFontContext(CDwFontContext const&);
+ void operator=(CDwFontContext const&);
+ HRESULT hr_;
+ IDWriteFactory* dwriteFactory_;
+};
+class CDwGdiTextRenderer : public CFX_Object
+{
+public:
+ CDwGdiTextRenderer(
+ CFX_DIBitmap* pBitmap,
+ IDWriteBitmapRenderTarget* bitmapRenderTarget,
+ IDWriteRenderingParams* renderingParams
+ );
+ CDwGdiTextRenderer::~CDwGdiTextRenderer();
+ HRESULT STDMETHODCALLTYPE DrawGlyphRun(
+ const FX_RECT& text_bbox,
+ __in_opt CFX_ClipRgn* pClipRgn,
+ __in_opt DWRITE_MATRIX const* pMatrix,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_MEASURING_MODE measuringMode,
+ __in DWRITE_GLYPH_RUN const* glyphRun,
+ const COLORREF& textColor
+ );
+private:
+ CFX_DIBitmap* pBitmap_;
+ IDWriteBitmapRenderTarget* pRenderTarget_;
+ IDWriteRenderingParams* pRenderingParams_;
+};
+CDWriteExt::CDWriteExt()
+{
+ m_hModule = NULL;
+ m_pDWriteFactory = NULL;
+ m_pDwFontContext = NULL;
+ m_pDwTextRenderer = NULL;
+}
+void CDWriteExt::Load()
+{
+}
+void CDWriteExt::Unload()
+{
+ if (m_pDwFontContext) {
+ delete (CDwFontContext*)m_pDwFontContext;
+ m_pDwFontContext = NULL;
+ }
+ SafeRelease((IDWriteFactory**)&m_pDWriteFactory);
+}
+CDWriteExt::~CDWriteExt()
+{
+ Unload();
+}
+LPVOID CDWriteExt::DwCreateFontFaceFromStream(FX_LPBYTE pData, FX_DWORD size, int simulation_style)
+{
+ IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
+ IDWriteFontFile* pDwFontFile = NULL;
+ IDWriteFontFace* pDwFontFace = NULL;
+ BOOL isSupportedFontType = FALSE;
+ DWRITE_FONT_FILE_TYPE fontFileType;
+ DWRITE_FONT_FACE_TYPE fontFaceType;
+ UINT32 numberOfFaces;
+ DWRITE_FONT_SIMULATIONS fontStyle = (DWRITE_FONT_SIMULATIONS)(simulation_style & 3);
+ HRESULT hr = S_OK;
+ hr = pDwFactory->CreateCustomFontFileReference(
+ (void const*)pData,
+ (UINT32)size,
+ CDwFontFileLoader::GetLoader(),
+ &pDwFontFile
+ );
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ hr = pDwFontFile->Analyze(
+ &isSupportedFontType,
+ &fontFileType,
+ &fontFaceType,
+ &numberOfFaces
+ );
+ if (FAILED(hr) || !isSupportedFontType || fontFaceType == DWRITE_FONT_FACE_TYPE_UNKNOWN) {
+ goto failed;
+ }
+ hr = pDwFactory->CreateFontFace(
+ fontFaceType,
+ 1,
+ &pDwFontFile,
+ 0,
+ fontStyle,
+ &pDwFontFace
+ );
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ SafeRelease(&pDwFontFile);
+ return pDwFontFace;
+failed:
+ SafeRelease(&pDwFontFile);
+ return NULL;
+}
+FX_BOOL CDWriteExt::DwCreateRenderingTarget(CFX_DIBitmap* pBitmap, void** renderTarget)
+{
+ if (pBitmap->GetFormat() > FXDIB_Argb) {
+ return FALSE;
+ }
+ IDWriteFactory* pDwFactory = (IDWriteFactory*)m_pDWriteFactory;
+ IDWriteGdiInterop* pGdiInterop = NULL;
+ IDWriteBitmapRenderTarget* pBitmapRenderTarget = NULL;
+ IDWriteRenderingParams* pRenderingParams = NULL;
+ HRESULT hr = S_OK;
+ hr = pDwFactory->GetGdiInterop(&pGdiInterop);
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ hr = pGdiInterop->CreateBitmapRenderTarget(NULL, pBitmap->GetWidth(), pBitmap->GetHeight(),
+ &pBitmapRenderTarget);
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ hr = pDwFactory->CreateCustomRenderingParams(
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ DWRITE_PIXEL_GEOMETRY_RGB,
+ DWRITE_RENDERING_MODE_DEFAULT,
+ &pRenderingParams
+ );
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ hr = pBitmapRenderTarget->SetPixelsPerDip(1.0f);
+ if (FAILED(hr)) {
+ goto failed;
+ }
+ *(CDwGdiTextRenderer**)renderTarget = FX_NEW CDwGdiTextRenderer(pBitmap, pBitmapRenderTarget, pRenderingParams);
+ if (*(CDwGdiTextRenderer**)renderTarget == NULL) {
+ goto failed;
+ }
+ SafeRelease(&pGdiInterop);
+ SafeRelease(&pBitmapRenderTarget);
+ SafeRelease(&pRenderingParams);
+ return TRUE;
+failed:
+ SafeRelease(&pGdiInterop);
+ SafeRelease(&pBitmapRenderTarget);
+ SafeRelease(&pRenderingParams);
+ return FALSE;
+}
+FX_BOOL CDWriteExt::DwRendingString(void* renderTarget, CFX_ClipRgn* pClipRgn, FX_RECT& stringRect, CFX_AffineMatrix* pMatrix,
+ void *font, FX_FLOAT font_size, FX_ARGB text_color,
+ int glyph_count, unsigned short* glyph_indices,
+ FX_FLOAT baselineOriginX, FX_FLOAT baselineOriginY,
+ void* glyph_offsets,
+ FX_FLOAT* glyph_advances)
+{
+ if (renderTarget == NULL) {
+ return TRUE;
+ }
+ CDwGdiTextRenderer* pTextRenderer = (CDwGdiTextRenderer*)renderTarget;
+ DWRITE_MATRIX transform;
+ DWRITE_GLYPH_RUN glyphRun;
+ HRESULT hr = S_OK;
+ if (pMatrix) {
+ transform.m11 = pMatrix->a;
+ transform.m12 = pMatrix->b;
+ transform.m21 = pMatrix->c;
+ transform.m22 = pMatrix->d;
+ transform.dx = pMatrix->e;
+ transform.dy = pMatrix->f;
+ }
+ glyphRun.fontFace = (IDWriteFontFace*)font;
+ glyphRun.fontEmSize = font_size;
+ glyphRun.glyphCount = glyph_count;
+ glyphRun.glyphIndices = glyph_indices;
+ glyphRun.glyphAdvances = glyph_advances;
+ glyphRun.glyphOffsets = (DWRITE_GLYPH_OFFSET*)glyph_offsets;
+ glyphRun.isSideways = FALSE;
+ glyphRun.bidiLevel = 0;
+ hr = pTextRenderer->DrawGlyphRun(
+ stringRect,
+ pClipRgn,
+ pMatrix ? &transform : NULL,
+ baselineOriginX, baselineOriginY,
+ DWRITE_MEASURING_MODE_NATURAL,
+ &glyphRun,
+ RGB(FXARGB_R(text_color), FXARGB_G(text_color), FXARGB_B(text_color))
+ );
+ return SUCCEEDED(hr) ? TRUE : FALSE;
+}
+void CDWriteExt::DwDeleteRenderingTarget(void* renderTarget)
+{
+ if (renderTarget) {
+ delete (CDwGdiTextRenderer*)renderTarget;
+ }
+}
+void CDWriteExt::DwDeleteFont(void* pFont)
+{
+ if (pFont) {
+ SafeRelease((IDWriteFontFace**)&pFont);
+ }
+}
+CDwFontFileStream::CDwFontFileStream(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize)
+{
+ refCount_ = 0;
+ resourcePtr_ = fontFileReferenceKey;
+ resourceSize_ = fontFileReferenceKeySize;
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileStream::QueryInterface(REFIID iid, void** ppvObject)
+{
+ if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) {
+ *ppvObject = this;
+ AddRef();
+ return S_OK;
+ } else {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+}
+ULONG STDMETHODCALLTYPE CDwFontFileStream::AddRef()
+{
+ return InterlockedIncrement((long*)(&refCount_));
+}
+ULONG STDMETHODCALLTYPE CDwFontFileStream::Release()
+{
+ ULONG newCount = InterlockedDecrement((long*)(&refCount_));
+ if (newCount == 0) {
+ delete this;
+ }
+ return newCount;
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileStream::ReadFileFragment(
+ void const** fragmentStart,
+ UINT64 fileOffset,
+ UINT64 fragmentSize,
+ OUT void** fragmentContext
+)
+{
+ if (fileOffset <= resourceSize_ &&
+ fragmentSize <= resourceSize_ - fileOffset) {
+ *fragmentStart = static_cast<FX_BYTE const*>(resourcePtr_) + static_cast<size_t>(fileOffset);
+ *fragmentContext = NULL;
+ return S_OK;
+ } else {
+ *fragmentStart = NULL;
+ *fragmentContext = NULL;
+ return E_FAIL;
+ }
+}
+void STDMETHODCALLTYPE CDwFontFileStream::ReleaseFileFragment(void* fragmentContext)
+{
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetFileSize(OUT UINT64* fileSize)
+{
+ *fileSize = resourceSize_;
+ return S_OK;
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileStream::GetLastWriteTime(OUT UINT64* lastWriteTime)
+{
+ *lastWriteTime = 0;
+ return E_NOTIMPL;
+}
+IDWriteFontFileLoader* CDwFontFileLoader::instance_ = NULL;
+CDwFontFileLoader::CDwFontFileLoader() :
+ refCount_(0)
+{
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileLoader::QueryInterface(REFIID iid, void** ppvObject)
+{
+ if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
+ *ppvObject = this;
+ AddRef();
+ return S_OK;
+ } else {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+}
+ULONG STDMETHODCALLTYPE CDwFontFileLoader::AddRef()
+{
+ return InterlockedIncrement((long*)(&refCount_));
+}
+ULONG STDMETHODCALLTYPE CDwFontFileLoader::Release()
+{
+ ULONG newCount = InterlockedDecrement((long*)(&refCount_));
+ if (newCount == 0) {
+ instance_ = NULL;
+ delete this;
+ }
+ return newCount;
+}
+HRESULT STDMETHODCALLTYPE CDwFontFileLoader::CreateStreamFromKey(
+ void const* fontFileReferenceKey,
+ UINT32 fontFileReferenceKeySize,
+ OUT IDWriteFontFileStream** fontFileStream
+)
+{
+ *fontFileStream = NULL;
+ CDwFontFileStream* stream = FX_NEW CDwFontFileStream(fontFileReferenceKey, fontFileReferenceKeySize);
+ if (stream == NULL) {
+ return E_OUTOFMEMORY;
+ }
+ if (!stream->IsInitialized()) {
+ delete stream;
+ return E_FAIL;
+ }
+ *fontFileStream = SafeAcquire(stream);
+ return S_OK;
+}
+CDwFontContext::CDwFontContext(IDWriteFactory* dwriteFactory) :
+ hr_(S_FALSE),
+ dwriteFactory_(SafeAcquire(dwriteFactory))
+{
+}
+CDwFontContext::~CDwFontContext()
+{
+ if(dwriteFactory_ && hr_ == S_OK) {
+ dwriteFactory_->UnregisterFontFileLoader(CDwFontFileLoader::GetLoader());
+ }
+ SafeRelease(&dwriteFactory_);
+}
+HRESULT CDwFontContext::Initialize()
+{
+ if (hr_ == S_FALSE) {
+ return hr_ = dwriteFactory_->RegisterFontFileLoader(CDwFontFileLoader::GetLoader());
+ }
+ return hr_;
+}
+CDwGdiTextRenderer::CDwGdiTextRenderer(CFX_DIBitmap* pBitmap, IDWriteBitmapRenderTarget* bitmapRenderTarget, IDWriteRenderingParams* renderingParams):
+ pBitmap_(pBitmap),
+ pRenderTarget_(SafeAcquire(bitmapRenderTarget)),
+ pRenderingParams_(SafeAcquire(renderingParams))
+{
+}
+CDwGdiTextRenderer::~CDwGdiTextRenderer()
+{
+ SafeRelease(&pRenderTarget_);
+ SafeRelease(&pRenderingParams_);
+}
+STDMETHODIMP CDwGdiTextRenderer::DrawGlyphRun(
+ const FX_RECT& text_bbox,
+ __in_opt CFX_ClipRgn* pClipRgn,
+ __in_opt DWRITE_MATRIX const* pMatrix,
+ FLOAT baselineOriginX,
+ FLOAT baselineOriginY,
+ DWRITE_MEASURING_MODE measuringMode,
+ __in DWRITE_GLYPH_RUN const* glyphRun,
+ const COLORREF& textColor
+)
+{
+ HRESULT hr = S_OK;
+ if (pMatrix) {
+ hr = pRenderTarget_->SetCurrentTransform(pMatrix);
+ if (FAILED(hr)) {
+ return hr;
+ }
+ }
+ HDC hDC = pRenderTarget_->GetMemoryDC();
+ HBITMAP hBitmap = (HBITMAP)::GetCurrentObject(hDC, OBJ_BITMAP);
+ BITMAP bitmap;
+ GetObject(hBitmap, sizeof bitmap, &bitmap);
+ CFX_DIBitmap dib;
+ dib.Create(
+ bitmap.bmWidth,
+ bitmap.bmHeight,
+ bitmap.bmBitsPixel == 24 ? FXDIB_Rgb : FXDIB_Rgb32,
+ (FX_LPBYTE)bitmap.bmBits
+ );
+ dib.CompositeBitmap(
+ text_bbox.left,
+ text_bbox.top,
+ text_bbox.Width(),
+ text_bbox.Height(),
+ pBitmap_,
+ text_bbox.left,
+ text_bbox.top,
+ FXDIB_BLEND_NORMAL,
+ NULL
+ );
+ hr = pRenderTarget_->DrawGlyphRun(
+ baselineOriginX,
+ baselineOriginY,
+ measuringMode,
+ glyphRun,
+ pRenderingParams_,
+ textColor
+ );
+ if (FAILED(hr)) {
+ return hr;
+ }
+ pBitmap_->CompositeBitmap(
+ text_bbox.left,
+ text_bbox.top,
+ text_bbox.Width(),
+ text_bbox.Height(),
+ &dib,
+ text_bbox.left,
+ text_bbox.top,
+ FXDIB_BLEND_NORMAL,
+ pClipRgn
+ );
+ return hr;
+}
+#endif
diff --git a/core/src/fxge/win32/fx_win32_gdipext.cpp b/core/src/fxge/win32/fx_win32_gdipext.cpp
index 7f9240629c..d3aeecc515 100644
--- a/core/src/fxge/win32/fx_win32_gdipext.cpp
+++ b/core/src/fxge/win32/fx_win32_gdipext.cpp
@@ -1,1286 +1,1286 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include <windows.h>
-#include "../../../include/fxge/fx_ge_win32.h"
-#include "win32_int.h"
-#include "../Microsoft SDK/include/GdiPlus.h"
-using namespace Gdiplus;
-using namespace Gdiplus::DllExports;
-#define GdiFillType2Gdip(fill_type) (fill_type == ALTERNATE ? FillModeAlternate : FillModeWinding)
-static CombineMode GdiCombineMode2Gdip(int mode)
-{
- switch (mode) {
- case RGN_AND:
- return CombineModeIntersect;
- }
- return CombineModeIntersect;
-}
-enum {
- FuncId_GdipCreatePath2,
- FuncId_GdipSetPenDashStyle,
- FuncId_GdipSetPenDashArray,
- FuncId_GdipSetPenDashCap197819,
- FuncId_GdipSetPenLineJoin,
- FuncId_GdipSetPenWidth,
- FuncId_GdipCreateFromHDC,
- FuncId_GdipSetPageUnit,
- FuncId_GdipSetSmoothingMode,
- FuncId_GdipCreateSolidFill,
- FuncId_GdipFillPath,
- FuncId_GdipDeleteBrush,
- FuncId_GdipCreatePen1,
- FuncId_GdipSetPenMiterLimit,
- FuncId_GdipDrawPath,
- FuncId_GdipDeletePen,
- FuncId_GdipDeletePath,
- FuncId_GdipDeleteGraphics,
- FuncId_GdipCreateBitmapFromFileICM,
- FuncId_GdipCreateBitmapFromStreamICM,
- FuncId_GdipGetImageHeight,
- FuncId_GdipGetImageWidth,
- FuncId_GdipGetImagePixelFormat,
- FuncId_GdipBitmapLockBits,
- FuncId_GdipGetImagePaletteSize,
- FuncId_GdipGetImagePalette,
- FuncId_GdipBitmapUnlockBits,
- FuncId_GdipDisposeImage,
- FuncId_GdipFillRectangle,
- FuncId_GdipCreateBitmapFromScan0,
- FuncId_GdipSetImagePalette,
- FuncId_GdipSetInterpolationMode,
- FuncId_GdipDrawImagePointsI,
- FuncId_GdipCreateBitmapFromGdiDib,
- FuncId_GdiplusStartup,
- FuncId_GdipDrawLineI,
- FuncId_GdipResetClip,
- FuncId_GdipCreatePath,
- FuncId_GdipAddPathPath,
- FuncId_GdipSetPathFillMode,
- FuncId_GdipSetClipPath,
- FuncId_GdipGetClip,
- FuncId_GdipCreateRegion,
- FuncId_GdipGetClipBoundsI,
- FuncId_GdipSetClipRegion,
- FuncId_GdipWidenPath,
- FuncId_GdipAddPathLine,
- FuncId_GdipAddPathRectangle,
- FuncId_GdipDeleteRegion,
- FuncId_GdipGetDC,
- FuncId_GdipReleaseDC,
- FuncId_GdipSetPenLineCap197819,
- FuncId_GdipSetPenDashOffset,
- FuncId_GdipResetPath,
- FuncId_GdipCreateRegionPath,
- FuncId_GdipCreateFont,
- FuncId_GdipGetFontSize,
- FuncId_GdipCreateFontFamilyFromName,
- FuncId_GdipSetTextRenderingHint,
- FuncId_GdipDrawDriverString,
- FuncId_GdipCreateMatrix2,
- FuncId_GdipDeleteMatrix,
- FuncId_GdipSetWorldTransform,
- FuncId_GdipResetWorldTransform,
- FuncId_GdipDeleteFontFamily,
- FuncId_GdipDeleteFont,
- FuncId_GdipNewPrivateFontCollection,
- FuncId_GdipDeletePrivateFontCollection,
- FuncId_GdipPrivateAddMemoryFont,
- FuncId_GdipGetFontCollectionFamilyList,
- FuncId_GdipGetFontCollectionFamilyCount,
- FuncId_GdipSetTextContrast,
- FuncId_GdipSetPixelOffsetMode,
- FuncId_GdipGetImageGraphicsContext,
- FuncId_GdipDrawImageI,
- FuncId_GdipDrawImageRectI,
- FuncId_GdipDrawString,
- FuncId_GdipSetPenTransform,
-};
-static LPCSTR g_GdipFuncNames[] = {
- "GdipCreatePath2",
- "GdipSetPenDashStyle",
- "GdipSetPenDashArray",
- "GdipSetPenDashCap197819",
- "GdipSetPenLineJoin",
- "GdipSetPenWidth",
- "GdipCreateFromHDC",
- "GdipSetPageUnit",
- "GdipSetSmoothingMode",
- "GdipCreateSolidFill",
- "GdipFillPath",
- "GdipDeleteBrush",
- "GdipCreatePen1",
- "GdipSetPenMiterLimit",
- "GdipDrawPath",
- "GdipDeletePen",
- "GdipDeletePath",
- "GdipDeleteGraphics",
- "GdipCreateBitmapFromFileICM",
- "GdipCreateBitmapFromStreamICM",
- "GdipGetImageHeight",
- "GdipGetImageWidth",
- "GdipGetImagePixelFormat",
- "GdipBitmapLockBits",
- "GdipGetImagePaletteSize",
- "GdipGetImagePalette",
- "GdipBitmapUnlockBits",
- "GdipDisposeImage",
- "GdipFillRectangle",
- "GdipCreateBitmapFromScan0",
- "GdipSetImagePalette",
- "GdipSetInterpolationMode",
- "GdipDrawImagePointsI",
- "GdipCreateBitmapFromGdiDib",
- "GdiplusStartup",
- "GdipDrawLineI",
- "GdipResetClip",
- "GdipCreatePath",
- "GdipAddPathPath",
- "GdipSetPathFillMode",
- "GdipSetClipPath",
- "GdipGetClip",
- "GdipCreateRegion",
- "GdipGetClipBoundsI",
- "GdipSetClipRegion",
- "GdipWidenPath",
- "GdipAddPathLine",
- "GdipAddPathRectangle",
- "GdipDeleteRegion",
- "GdipGetDC",
- "GdipReleaseDC",
- "GdipSetPenLineCap197819",
- "GdipSetPenDashOffset",
- "GdipResetPath",
- "GdipCreateRegionPath",
- "GdipCreateFont",
- "GdipGetFontSize",
- "GdipCreateFontFamilyFromName",
- "GdipSetTextRenderingHint",
- "GdipDrawDriverString",
- "GdipCreateMatrix2",
- "GdipDeleteMatrix",
- "GdipSetWorldTransform",
- "GdipResetWorldTransform",
- "GdipDeleteFontFamily",
- "GdipDeleteFont",
- "GdipNewPrivateFontCollection",
- "GdipDeletePrivateFontCollection",
- "GdipPrivateAddMemoryFont",
- "GdipGetFontCollectionFamilyList",
- "GdipGetFontCollectionFamilyCount",
- "GdipSetTextContrast",
- "GdipSetPixelOffsetMode",
- "GdipGetImageGraphicsContext",
- "GdipDrawImageI",
- "GdipDrawImageRectI",
- "GdipDrawString",
- "GdipSetPenTransform",
-};
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath2)(GDIPCONST GpPointF*, GDIPCONST BYTE*, INT, GpFillMode, GpPath **path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashStyle)(GpPen *pen, GpDashStyle dashstyle);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashArray)(GpPen *pen, GDIPCONST REAL *dash, INT count);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashCap197819)(GpPen *pen, GpDashCap dashCap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineJoin)(GpPen *pen, GpLineJoin lineJoin);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenWidth)(GpPen *pen, REAL width);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFromHDC)(HDC hdc, GpGraphics **graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPageUnit)(GpGraphics *graphics, GpUnit unit);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetSmoothingMode)(GpGraphics *graphics, SmoothingMode smoothingMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateSolidFill)(ARGB color, GpSolidFill **brush);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipFillPath)(GpGraphics *graphics, GpBrush *brush, GpPath *path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteBrush)(GpBrush *brush);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePen1)(ARGB color, REAL width, GpUnit unit, GpPen **pen);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenMiterLimit)(GpPen *pen, REAL miterLimit);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawPath)(GpGraphics *graphics, GpPen *pen, GpPath *path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePen)(GpPen *pen);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePath)(GpPath* path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteGraphics)(GpGraphics *graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromFileICM)(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromStreamICM)(IStream* stream, GpBitmap **bitmap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageWidth)(GpImage *image, UINT *width);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageHeight)(GpImage *image, UINT *height);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePixelFormat)(GpImage *image, PixelFormat *format);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapLockBits)(GpBitmap* bitmap, GDIPCONST GpRect* rect, UINT flags, PixelFormat format, BitmapData* lockedBitmapData);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePalette)(GpImage *image, ColorPalette *palette, INT size);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePaletteSize)(GpImage *image, INT *size);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapUnlockBits)(GpBitmap* bitmap, BitmapData* lockedBitmapData);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDisposeImage)(GpImage *image);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipFillRectangle)(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromScan0)(INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, GpBitmap** bitmap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetImagePalette)(GpImage *image, GDIPCONST ColorPalette *palette);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetInterpolationMode)(GpGraphics *graphics, InterpolationMode interpolationMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImagePointsI)(GpGraphics *graphics, GpImage *image, GDIPCONST GpPoint *dstpoints, INT count);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromGdiDib)(GDIPCONST BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData, GpBitmap** bitmap);
-typedef Status (WINAPI *FuncType_GdiplusStartup)(OUT FX_UINTPTR *token, const GdiplusStartupInput *input, OUT GdiplusStartupOutput *output);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawLineI)(GpGraphics *graphics, GpPen *pen, int x1, int y1, int x2, int y2);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipResetClip)(GpGraphics *graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath)(GpFillMode brushMode, GpPath **path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathPath)(GpPath *path, GDIPCONST GpPath* addingPath, BOOL connect);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPathFillMode)(GpPath *path, GpFillMode fillmode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipPath)(GpGraphics *graphics, GpPath *path, CombineMode combineMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClip)(GpGraphics *graphics, GpRegion *region);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegion)(GpRegion **region);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClipBoundsI)(GpGraphics *graphics, GpRect *rect);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipRegion)(GpGraphics *graphics, GpRegion *region, CombineMode combineMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipWidenPath)(GpPath *nativePath, GpPen *pen, GpMatrix *matrix, REAL flatness);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathLine)(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathRectangle)(GpPath *path, REAL x, REAL y, REAL width, REAL height);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteRegion)(GpRegion *region);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetDC)(GpGraphics* graphics, HDC * hdc);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipReleaseDC)(GpGraphics* graphics, HDC hdc);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineCap197819)(GpPen *pen, GpLineCap startCap, GpLineCap endCap, GpDashCap dashCap);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashOffset)(GpPen *pen, REAL offset);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipResetPath)(GpPath *path);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegionPath)(GpPath *path, GpRegion **region);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFont)(GDIPCONST GpFontFamily *fontFamily, REAL emSize, INT style, Unit unit, GpFont **font);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontSize)(GpFont *font, REAL *size);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFontFamilyFromName)(GDIPCONST WCHAR *name, GpFontCollection *fontCollection, GpFontFamily **FontFamily);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextRenderingHint)(GpGraphics *graphics, TextRenderingHint mode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawDriverString)(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateMatrix2)(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteMatrix)(GpMatrix *matrix);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetWorldTransform)(GpGraphics *graphics, GpMatrix *matrix);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipResetWorldTransform)(GpGraphics *graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFontFamily)(GpFontFamily *FontFamily);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFont)(GpFont* font);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipNewPrivateFontCollection)(GpFontCollection** fontCollection);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePrivateFontCollection)(GpFontCollection** fontCollection);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipPrivateAddMemoryFont)(GpFontCollection* fontCollection, GDIPCONST void* memory, INT length);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyList)(GpFontCollection* fontCollection, INT numSought, GpFontFamily* gpfamilies[], INT* numFound);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyCount)(GpFontCollection* fontCollection, INT* numFound);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextContrast)(GpGraphics *graphics, UINT contrast);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPixelOffsetMode)(GpGraphics* graphics, PixelOffsetMode pixelOffsetMode);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageGraphicsContext)(GpImage *image, GpGraphics **graphics);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageI)(GpGraphics *graphics, GpImage *image, INT x, INT y);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageRectI)(GpGraphics *graphics, GpImage *image, INT x, INT y, INT width, INT height);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawString)(GpGraphics *graphics, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *stringFormat, GDIPCONST GpBrush *brush);
-typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenTransform)(GpPen *pen, GpMatrix *matrix);
-#define CallFunc(funcname) ((FuncType_##funcname)GdiplusExt.m_Functions[FuncId_##funcname])
-typedef HANDLE (__stdcall *FuncType_GdiAddFontMemResourceEx)(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD *pcFonts);
-typedef BOOL (__stdcall *FuncType_GdiRemoveFontMemResourceEx)(HANDLE handle);
-void* CGdiplusExt::GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face)
-{
- if (m_pGdiAddFontMemResourceEx) {
- return ((FuncType_GdiAddFontMemResourceEx)m_pGdiAddFontMemResourceEx)((PVOID)pFontdata, (DWORD)size, (PVOID)pdv, (DWORD*)num_face);
- }
- return NULL;
-}
-FX_BOOL CGdiplusExt::GdiRemoveFontMemResourceEx(void* handle)
-{
- if (m_pGdiRemoveFontMemResourseEx) {
- return ((FuncType_GdiRemoveFontMemResourceEx)m_pGdiRemoveFontMemResourseEx)((HANDLE)handle);
- }
- return FALSE;
-}
-static GpBrush* _GdipCreateBrush(DWORD argb)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpSolidFill* solidBrush = NULL;
- CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
- return solidBrush;
-}
-static CFX_DIBitmap* _StretchMonoToGray(int dest_width, int dest_height,
- const CFX_DIBitmap* pSource, FX_RECT* pClipRect)
-{
- FX_BOOL bFlipX = dest_width < 0;
- if (bFlipX) {
- dest_width = -dest_width;
- }
- FX_BOOL bFlipY = dest_height < 0;
- if (bFlipY) {
- dest_height = -dest_height;
- }
- int result_width = pClipRect->Width();
- int result_height = pClipRect->Height();
- int result_pitch = (result_width + 3) / 4 * 4;
- CFX_DIBitmap* pStretched = FX_NEW CFX_DIBitmap;
- if (!pStretched) {
- return NULL;
- }
- if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) {
- delete pStretched;
- return NULL;
- }
- LPBYTE dest_buf = pStretched->GetBuffer();
- int src_width = pSource->GetWidth();
- int src_height = pSource->GetHeight();
- int src_count = src_width * src_height;
- int dest_count = dest_width * dest_height;
- int ratio = 255 * dest_count / src_count;
- int y_unit = src_height / dest_height;
- int x_unit = src_width / dest_width;
- int area_unit = y_unit * x_unit;
- LPBYTE src_buf = pSource->GetBuffer();
- int src_pitch = pSource->GetPitch();
- for (int dest_y = 0; dest_y < result_height; dest_y ++) {
- LPBYTE dest_scan = dest_buf + dest_y * result_pitch;
- int src_y_start = bFlipY ? (dest_height - 1 - dest_y - pClipRect->top) : (dest_y + pClipRect->top);
- src_y_start = src_y_start * src_height / dest_height;
- LPBYTE src_scan = src_buf + src_y_start * src_pitch;
- for (int dest_x = 0; dest_x < result_width; dest_x ++) {
- int sum = 0;
- int src_x_start = bFlipX ? (dest_width - 1 - dest_x - pClipRect->left) : (dest_x + pClipRect->left);
- src_x_start = src_x_start * src_width / dest_width;
- int src_x_end = src_x_start + x_unit;
- LPBYTE src_line = src_scan;
- for (int src_y = 0; src_y < y_unit; src_y ++) {
- for (int src_x = src_x_start; src_x < src_x_end; src_x ++) {
- if (!(src_line[src_x / 8] & (1 << (7 - src_x % 8)))) {
- sum += 255;
- }
- }
- src_line += src_pitch;
- }
- dest_scan[dest_x] = 255 - sum / area_unit;
- }
- }
- return pStretched;
-}
-static void OutputImageMask(GpGraphics* pGraphics, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_ARGB argb, const FX_RECT* pClipRect)
-{
- ASSERT(pBitmap->GetBPP() == 1);
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- int src_width = pBitmap->GetWidth(), src_height = pBitmap->GetHeight();
- int src_pitch = pBitmap->GetPitch();
- FX_LPBYTE scan0 = pBitmap->GetBuffer();
- if (src_width == 1 && src_height == 1) {
- if ((scan0[0] & 0x80) == 0) {
- return;
- }
- GpSolidFill* solidBrush;
- CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
- if (dest_width < 0) {
- dest_width = -dest_width;
- dest_left -= dest_width;
- }
- if (dest_height < 0) {
- dest_height = -dest_height;
- dest_top -= dest_height;
- }
- CallFunc(GdipFillRectangle)(pGraphics, solidBrush, (float)dest_left, (float)dest_top,
- (float)dest_width, (float)dest_height);
- CallFunc(GdipDeleteBrush)(solidBrush);
- return;
- }
- if (!bMonoDevice && abs(dest_width) < src_width && abs(dest_height) < src_height) {
- FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, dest_top + dest_height);
- image_rect.Normalize();
- FX_RECT image_clip = image_rect;
- image_clip.Intersect(*pClipRect);
- if (image_clip.IsEmpty()) {
- return;
- }
- image_clip.Offset(-image_rect.left, -image_rect.top);
- CFX_DIBitmap* pStretched = NULL;
- if (src_width * src_height > 10000) {
- pStretched = _StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip);
- } else {
- pStretched = pBitmap->StretchTo(dest_width, dest_height, FALSE, &image_clip);
- }
- GpBitmap* bitmap;
- CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(),
- (image_clip.Width() + 3) / 4 * 4, PixelFormat8bppIndexed, pStretched->GetBuffer(), &bitmap);
- int a, r, g, b;
- ArgbDecode(argb, a, r, g, b);
- UINT pal[258];
- pal[0] = 0;
- pal[1] = 256;
- for (int i = 0; i < 256; i ++) {
- pal[i + 2] = ArgbEncode(i * a / 255, r, g, b);
- }
- CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
- CallFunc(GdipDrawImageI)(pGraphics, bitmap, image_rect.left + image_clip.left,
- image_rect.top + image_clip.top);
- CallFunc(GdipDisposeImage)(bitmap);
- delete pStretched;
- return;
- }
- GpBitmap* bitmap;
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, PixelFormat1bppIndexed, scan0, &bitmap);
- UINT palette[4] = { PaletteFlagsHasAlpha, 2, 0, argb };
- CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette);
- Point destinationPoints[] = {
- Point(dest_left, dest_top),
- Point(dest_left + dest_width, dest_top),
- Point(dest_left, dest_top + dest_height)
- };
- CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
- CallFunc(GdipDisposeImage)(bitmap);
-}
-static void OutputImage(GpGraphics* pGraphics, const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect,
- int dest_left, int dest_top, int dest_width, int dest_height)
-{
- int src_width = pSrcRect->Width(), src_height = pSrcRect->Height();
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) {
- FX_RECT new_rect(0, 0, src_width, src_height);
- CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect);
- if (!pCloned) {
- return;
- }
- OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_width, dest_height);
- delete pCloned;
- return;
- }
- int src_pitch = pBitmap->GetPitch();
- FX_LPBYTE scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + pBitmap->GetBPP() * pSrcRect->left / 8;
- GpBitmap* bitmap = NULL;
- switch (pBitmap->GetFormat()) {
- case FXDIB_Argb:
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat32bppARGB, scan0, &bitmap);
- break;
- case FXDIB_Rgb32:
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat32bppRGB, scan0, &bitmap);
- break;
- case FXDIB_Rgb:
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat24bppRGB, scan0, &bitmap);
- break;
- case FXDIB_8bppRgb: {
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat8bppIndexed, scan0, &bitmap);
- UINT pal[258];
- pal[0] = 0;
- pal[1] = 256;
- for (int i = 0; i < 256; i ++) {
- pal[i + 2] = pBitmap->GetPaletteEntry(i);
- }
- CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
- break;
- }
- case FXDIB_1bppRgb: {
- CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
- PixelFormat1bppIndexed, scan0, &bitmap);
- break;
- }
- }
- if (dest_height < 0) {
- dest_height --;
- }
- if (dest_width < 0) {
- dest_width --;
- }
- Point destinationPoints[] = {
- Point(dest_left, dest_top),
- Point(dest_left + dest_width, dest_top),
- Point(dest_left, dest_top + dest_height)
- };
- CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
- CallFunc(GdipDisposeImage)(bitmap);
-}
-CGdiplusExt::CGdiplusExt()
-{
- m_hModule = NULL;
- m_GdiModule = NULL;
- for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
- m_Functions[i] = NULL;
- }
- m_pGdiAddFontMemResourceEx = NULL;
- m_pGdiRemoveFontMemResourseEx = NULL;
-}
-void CGdiplusExt::Load()
-{
- CFX_ByteString strPlusPath = "";
- FX_CHAR buf[MAX_PATH];
- GetSystemDirectoryA(buf, MAX_PATH);
- strPlusPath += buf;
- strPlusPath += "\\";
- strPlusPath += "GDIPLUS.DLL";
- m_hModule = LoadLibraryA(strPlusPath);
- if (m_hModule == NULL) {
- return;
- }
- for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
- m_Functions[i] = GetProcAddress(m_hModule, g_GdipFuncNames[i]);
- if (m_Functions[i] == NULL) {
- m_hModule = NULL;
- return;
- }
- }
- FX_UINTPTR gdiplusToken;
- GdiplusStartupInput gdiplusStartupInput;
- ((FuncType_GdiplusStartup)m_Functions[FuncId_GdiplusStartup])(&gdiplusToken, &gdiplusStartupInput, NULL);
- m_GdiModule = LoadLibraryA("GDI32.DLL");
- if (m_GdiModule == NULL) {
- return;
- }
- m_pGdiAddFontMemResourceEx = GetProcAddress(m_GdiModule, "AddFontMemResourceEx");
- m_pGdiRemoveFontMemResourseEx = GetProcAddress(m_GdiModule, "RemoveFontMemResourceEx");
-}
-CGdiplusExt::~CGdiplusExt()
-{
-}
-LPVOID CGdiplusExt::LoadMemFont(LPBYTE pData, FX_DWORD size)
-{
- GpFontCollection* pCollection = NULL;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipNewPrivateFontCollection)(&pCollection);
- GpStatus status = CallFunc(GdipPrivateAddMemoryFont)(pCollection, pData, size);
- if (status == Ok) {
- return pCollection;
- }
- CallFunc(GdipDeletePrivateFontCollection)(&pCollection);
- return NULL;
-}
-void CGdiplusExt::DeleteMemFont(LPVOID pCollection)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeletePrivateFontCollection)((GpFontCollection**)&pCollection);
-}
-FX_BOOL CGdiplusExt::GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- PixelFormat format;
- switch (pBitmap->GetFormat()) {
- case FXDIB_Rgb:
- format = PixelFormat24bppRGB;
- break;
- case FXDIB_Rgb32:
- format = PixelFormat32bppRGB;
- break;
- case FXDIB_Argb:
- format = PixelFormat32bppARGB;
- break;
- default:
- return FALSE;
- }
- GpStatus status = CallFunc(GdipCreateBitmapFromScan0)(pBitmap->GetWidth(), pBitmap->GetHeight(),
- pBitmap->GetPitch(), format, pBitmap->GetBuffer(), (GpBitmap**)bitmap);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CGdiplusExt::GdipCreateFromImage(void* bitmap, void** graphics)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipGetImageGraphicsContext)((GpBitmap*)bitmap, (GpGraphics**)graphics);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CGdiplusExt::GdipCreateFontFamilyFromName(FX_LPCWSTR name, void* pFontCollection, void**pFamily)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipCreateFontFamilyFromName)((GDIPCONST WCHAR *)name, (GpFontCollection*)pFontCollection, (GpFontFamily**)pFamily);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CGdiplusExt::GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipCreateFont)((GpFontFamily*)pFamily, font_size, fontstyle, Unit(flag), (GpFont**)pFont);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-void CGdiplusExt::GdipGetFontSize(void *pFont, FX_FLOAT *size)
-{
- REAL get_size;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipGetFontSize)((GpFont *)pFont, (REAL*)&get_size);
- if (status == Ok) {
- *size = (FX_FLOAT)get_size;
- } else {
- *size = 0;
- }
-}
-void CGdiplusExt::GdipSetTextRenderingHint(void* graphics, int mode)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipSetTextRenderingHint)((GpGraphics*)graphics, (TextRenderingHint)mode);
-}
-void CGdiplusExt::GdipSetPageUnit(void* graphics, FX_DWORD unit)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipSetPageUnit)((GpGraphics*)graphics, (GpUnit)unit);
-}
-FX_BOOL CGdiplusExt::GdipDrawDriverString(void *graphics, unsigned short *text, int length,
- void *font, void* brush, void *positions, int flags, const void *matrix)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpStatus status = CallFunc(GdipDrawDriverString)((GpGraphics*)graphics, (GDIPCONST UINT16 *)text, (INT)length, (GDIPCONST GpFont *)font, (GDIPCONST GpBrush*)brush,
- (GDIPCONST PointF *)positions, (INT)flags, (GDIPCONST GpMatrix *)matrix);
- if (status == Ok) {
- return TRUE;
- }
- return FALSE;
-}
-void CGdiplusExt::GdipCreateBrush(FX_DWORD fill_argb, void** pBrush)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipCreateSolidFill)((ARGB)fill_argb, (GpSolidFill**)pBrush);
-}
-void CGdiplusExt::GdipDeleteBrush(void* pBrush)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteBrush)((GpSolidFill*)pBrush);
-}
-void* CGdiplusExt::GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- int numFamilies = 0;
- GpStatus status = CallFunc(GdipGetFontCollectionFamilyCount)((GpFontCollection*)pFontCollection, &numFamilies);
- if (status != Ok) {
- return NULL;
- }
- GpFontFamily* family_list[1];
- status = CallFunc(GdipGetFontCollectionFamilyList)((GpFontCollection*)pFontCollection, 1, family_list, &numFamilies);
- if (status != Ok) {
- return NULL;
- }
- GpFont* pFont = NULL;
- status = CallFunc(GdipCreateFont)(family_list[0], font_size, fontstyle, UnitPixel, &pFont);
- if (status != Ok) {
- return NULL;
- }
- return pFont;
-}
-void CGdiplusExt::GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipCreateMatrix2)(a, b, c, d, e, f, (GpMatrix**)matrix);
-}
-void CGdiplusExt::GdipDeleteMatrix(void* matrix)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteMatrix)((GpMatrix*)matrix);
-}
-void CGdiplusExt::GdipDeleteFontFamily(void* pFamily)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteFontFamily)((GpFontFamily*)pFamily);
-}
-void CGdiplusExt::GdipDeleteFont(void* pFont)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteFont)((GpFont*)pFont);
-}
-void CGdiplusExt::GdipSetWorldTransform(void* graphics, void* pMatrix)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipSetWorldTransform)((GpGraphics*)graphics, (GpMatrix*)pMatrix);
-}
-void CGdiplusExt::GdipDisposeImage(void* bitmap)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDisposeImage)((GpBitmap*)bitmap);
-}
-void CGdiplusExt::GdipDeleteGraphics(void* graphics)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipDeleteGraphics)((GpGraphics*)graphics);
-}
-FX_BOOL CGdiplusExt::StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags)
-{
- ASSERT(pBitmap->GetBPP() == 1);
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- GpGraphics* pGraphics = NULL;
- CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
- CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
- if (flags & FXDIB_NOSMOOTH) {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor);
- } else {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
- }
- OutputImageMask(pGraphics, bMonoDevice, pBitmap, dest_left, dest_top, dest_width, dest_height, argb, pClipRect);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- return TRUE;
-}
-FX_BOOL CGdiplusExt::StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, int flags)
-{
- GpGraphics* pGraphics;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
- CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
- if (flags & FXDIB_NOSMOOTH) {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor);
- } else if (pBitmap->GetWidth() > abs(dest_width) / 2 || pBitmap->GetHeight() > abs(dest_height) / 2) {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
- } else {
- CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeBilinear);
- }
- FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
- OutputImage(pGraphics, pBitmap, &src_rect, dest_left, dest_top, dest_width, dest_height);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- return TRUE;
-}
-static GpPen* _GdipCreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, DWORD argb, FX_BOOL bTextMode = FALSE)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- FX_FLOAT width = pGraphState ? pGraphState->m_LineWidth : 1.0f;
- if (!bTextMode) {
- FX_FLOAT unit = pMatrix == NULL ? 1.0f : FXSYS_Div(1.0f, (pMatrix->GetXUnit() + pMatrix->GetYUnit()) / 2);
- if (width < unit) {
- width = unit;
- }
- }
- GpPen* pPen = NULL;
- CallFunc(GdipCreatePen1)((ARGB)argb, width, UnitWorld, &pPen);
- LineCap lineCap;
- DashCap dashCap = DashCapFlat;
- FX_BOOL bDashExtend = FALSE;
- switch(pGraphState->m_LineCap) {
- case CFX_GraphStateData::LineCapButt:
- lineCap = LineCapFlat;
- break;
- case CFX_GraphStateData::LineCapRound:
- lineCap = LineCapRound;
- dashCap = DashCapRound;
- bDashExtend = TRUE;
- break;
- case CFX_GraphStateData::LineCapSquare:
- lineCap = LineCapSquare;
- bDashExtend = TRUE;
- break;
- }
- CallFunc(GdipSetPenLineCap197819)(pPen, lineCap, lineCap, dashCap);
- LineJoin lineJoin;
- switch(pGraphState->m_LineJoin) {
- case CFX_GraphStateData::LineJoinMiter:
- lineJoin = LineJoinMiterClipped;
- break;
- case CFX_GraphStateData::LineJoinRound:
- lineJoin = LineJoinRound;
- break;
- case CFX_GraphStateData::LineJoinBevel:
- lineJoin = LineJoinBevel;
- break;
- }
- CallFunc(GdipSetPenLineJoin)(pPen, lineJoin);
- if(pGraphState->m_DashCount) {
- FX_FLOAT* pDashArray = FX_Alloc(FX_FLOAT, pGraphState->m_DashCount + pGraphState->m_DashCount % 2);
- if (!pDashArray) {
- return NULL;
- }
- int nCount = 0;
- FX_FLOAT on_leftover = 0, off_leftover = 0;
- for (int i = 0; i < pGraphState->m_DashCount; i += 2) {
- FX_FLOAT on_phase = pGraphState->m_DashArray[i];
- FX_FLOAT off_phase;
- if (i == pGraphState->m_DashCount - 1) {
- off_phase = on_phase;
- } else {
- off_phase = pGraphState->m_DashArray[i + 1];
- }
- on_phase /= width;
- off_phase /= width;
- if (on_phase + off_phase <= 0.00002f) {
- on_phase = 1.0f / 10;
- off_phase = 1.0f / 10;
- }
- if (bDashExtend) {
- if (off_phase < 1) {
- off_phase = 0;
- } else {
- off_phase -= 1;
- }
- on_phase += 1;
- }
- if (on_phase == 0 || off_phase == 0) {
- if (nCount == 0) {
- on_leftover += on_phase;
- off_leftover += off_phase;
- } else {
- pDashArray[nCount - 2] += on_phase;
- pDashArray[nCount - 1] += off_phase;
- }
- } else {
- pDashArray[nCount++] = on_phase + on_leftover;
- on_leftover = 0;
- pDashArray[nCount++] = off_phase + off_leftover;
- off_leftover = 0;
- }
- }
- CallFunc(GdipSetPenDashArray)(pPen, pDashArray, nCount);
- FX_FLOAT phase = pGraphState->m_DashPhase;
- if (bDashExtend)
- if (phase < 0.5f) {
- phase = 0;
- } else {
- phase -= 0.5f;
- }
- CallFunc(GdipSetPenDashOffset)(pPen, phase);
- FX_Free(pDashArray);
- pDashArray = NULL;
- }
- CallFunc(GdipSetPenMiterLimit)(pPen, pGraphState->m_MiterLimit);
- return pPen;
-}
-static BOOL IsSmallTriangle(PointF* points, const CFX_AffineMatrix* pMatrix, int& v1, int& v2)
-{
- int pairs[] = {1, 2, 0, 2, 0, 1};
- for (int i = 0; i < 3; i ++) {
- int pair1 = pairs[i * 2];
- int pair2 = pairs[i * 2 + 1];
- FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X;
- FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y;
- if (pMatrix) {
- pMatrix->Transform(x1, y1);
- pMatrix->Transform(x2, y2);
- }
- FX_FLOAT dx = x1 - x2;
- FX_FLOAT dy = y1 - y2;
- FX_FLOAT distance_square = FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy);
- if (distance_square < (1.0f * 2 + 1.0f / 4)) {
- v1 = i;
- v2 = pair1;
- return TRUE;
- }
- }
- return FALSE;
-}
-BOOL CGdiplusExt::DrawPath(HDC hDC, const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_argb,
- FX_DWORD stroke_argb,
- int fill_mode
- )
-{
- int nPoints = pPathData->GetPointCount();
- if (nPoints == 0) {
- return TRUE;
- }
- FX_PATHPOINT* pPoints = pPathData->GetPoints();
- GpGraphics* pGraphics = NULL;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
- CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
- CallFunc(GdipSetPixelOffsetMode)(pGraphics, PixelOffsetModeHalf);
- GpMatrix* pMatrix = NULL;
- if (pObject2Device) {
- CallFunc(GdipCreateMatrix2)(pObject2Device->a, pObject2Device->b, pObject2Device->c, pObject2Device->d, pObject2Device->e, pObject2Device->f, &pMatrix);
- CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix);
- }
- PointF *points = FX_Alloc(PointF, nPoints);
- if (!points) {
- return FALSE;
- }
- BYTE * types = FX_Alloc(BYTE, nPoints);
- if (!types) {
- FX_Free(points);
- return FALSE;
- }
- int nSubPathes = 0;
- FX_BOOL bSubClose = FALSE;
- int pos_subclose = 0;
- FX_BOOL bSmooth = FALSE;
- int startpoint = 0;
- for(int i = 0; i < nPoints; i++) {
- points[i].X = pPoints[i].m_PointX;
- points[i].Y = pPoints[i].m_PointY;
- FX_FLOAT x, y;
- if (pObject2Device) {
- pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y);
- } else {
- x = pPoints[i].m_PointX;
- y = pPoints[i].m_PointY;
- }
- if (x > 50000 * 1.0f) {
- points[i].X = 50000 * 1.0f;
- }
- if (x < -50000 * 1.0f) {
- points[i].X = -50000 * 1.0f;
- }
- if (y > 50000 * 1.0f) {
- points[i].Y = 50000 * 1.0f;
- }
- if (y < -50000 * 1.0f) {
- points[i].Y = -50000 * 1.0f;
- }
- int point_type = pPoints[i].m_Flag & FXPT_TYPE;
- if(point_type == FXPT_MOVETO) {
- types[i] = PathPointTypeStart;
- nSubPathes ++;
- bSubClose = FALSE;
- startpoint = i;
- } else if (point_type == FXPT_LINETO) {
- types[i] = PathPointTypeLine;
- if (pPoints[i - 1].m_Flag == FXPT_MOVETO && (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) &&
- points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) {
- points[i].X += 0.01f;
- continue;
- }
- if (!bSmooth && points[i].X != points[i - 1].X && points[i].Y != points[i - 1].Y) {
- bSmooth = TRUE;
- }
- } else if (point_type == FXPT_BEZIERTO) {
- types[i] = PathPointTypeBezier;
- bSmooth = TRUE;
- }
- if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) {
- if (bSubClose) {
- types[pos_subclose] &= ~PathPointTypeCloseSubpath;
- } else {
- bSubClose = TRUE;
- }
- pos_subclose = i;
- types[i] |= PathPointTypeCloseSubpath;
- if (!bSmooth && points[i].X != points[startpoint].X && points[i].Y != points[startpoint].Y) {
- bSmooth = TRUE;
- }
- }
- }
- if (fill_mode & FXFILL_NOPATHSMOOTH) {
- bSmooth = FALSE;
- CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeNone);
- } else if (!(fill_mode & FXFILL_FULLCOVER)) {
- if (!bSmooth && (fill_mode & 3)) {
- bSmooth = TRUE;
- }
- if (bSmooth || pGraphState && pGraphState->m_LineWidth > 2) {
- CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeAntiAlias);
- }
- }
- int new_fill_mode = fill_mode & 3;
- if (nPoints == 4 && pGraphState == NULL) {
- int v1, v2;
- if (IsSmallTriangle(points, pObject2Device, v1, v2)) {
- GpPen* pPen = NULL;
- CallFunc(GdipCreatePen1)(fill_argb, 1.0f, UnitPixel, &pPen);
- CallFunc(GdipDrawLineI)(pGraphics, pPen, FXSYS_round(points[v1].X), FXSYS_round(points[v1].Y),
- FXSYS_round(points[v2].X), FXSYS_round(points[v2].Y));
- CallFunc(GdipDeletePen)(pPen);
- return TRUE;
- }
- }
- GpPath* pGpPath = NULL;
- CallFunc(GdipCreatePath2)(points, types, nPoints, GdiFillType2Gdip(new_fill_mode), &pGpPath);
- if (!pGpPath) {
- if (pMatrix) {
- CallFunc(GdipDeleteMatrix)(pMatrix);
- }
- FX_Free(points);
- FX_Free(types);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- return FALSE;
- }
- if (new_fill_mode) {
- GpBrush* pBrush = _GdipCreateBrush(fill_argb);
- CallFunc(GdipSetPathFillMode)(pGpPath, GdiFillType2Gdip(new_fill_mode));
- CallFunc(GdipFillPath)(pGraphics, pBrush, pGpPath);
- CallFunc(GdipDeleteBrush)(pBrush);
- }
- if (pGraphState && stroke_argb) {
- GpPen* pPen = _GdipCreatePen(pGraphState, pObject2Device, stroke_argb, fill_mode & FX_STROKE_TEXT_MODE);
- if (nSubPathes == 1) {
- CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath);
- } else {
- int iStart = 0;
- for (int i = 0; i < nPoints; i ++) {
- if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) {
- GpPath* pSubPath;
- CallFunc(GdipCreatePath2)(points + iStart, types + iStart, i - iStart + 1, GdiFillType2Gdip(new_fill_mode), &pSubPath);
- iStart = i + 1;
- CallFunc(GdipDrawPath)(pGraphics, pPen, pSubPath);
- CallFunc(GdipDeletePath)(pSubPath);
- }
- }
- }
- CallFunc(GdipDeletePen)(pPen);
- }
- if (pMatrix) {
- CallFunc(GdipDeleteMatrix)(pMatrix);
- }
- FX_Free(points);
- FX_Free(types);
- CallFunc(GdipDeletePath)(pGpPath);
- CallFunc(GdipDeleteGraphics)(pGraphics);
- return TRUE;
-}
-class GpStream : public IStream, public CFX_Object
-{
- LONG m_RefCount;
- int m_ReadPos;
- CFX_ByteTextBuf m_InterStream;
-public:
- GpStream()
- {
- m_RefCount = 1;
- m_ReadPos = 0;
- }
- virtual HRESULT STDMETHODCALLTYPE
- QueryInterface(REFIID iid, void ** ppvObject)
- {
- if (iid == __uuidof(IUnknown) || iid == __uuidof(IStream) ||
- iid == __uuidof(ISequentialStream)) {
- *ppvObject = static_cast<IStream*>(this);
- AddRef();
- return S_OK;
- } else {
- return E_NOINTERFACE;
- }
- }
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- return (ULONG)InterlockedIncrement(&m_RefCount);
- }
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- ULONG res = (ULONG) InterlockedDecrement(&m_RefCount);
- if (res == 0) {
- delete this;
- }
- return res;
- }
-public:
- virtual HRESULT STDMETHODCALLTYPE Read(void* Output, ULONG cb, ULONG* pcbRead)
- {
- size_t bytes_left;
- size_t bytes_out;
- if (pcbRead != NULL) {
- *pcbRead = 0;
- }
- if (m_ReadPos == m_InterStream.GetLength()) {
- return HRESULT_FROM_WIN32(ERROR_END_OF_MEDIA);
- }
- bytes_left = m_InterStream.GetLength() - m_ReadPos;
- bytes_out = FX_MIN(cb, bytes_left);
- FXSYS_memcpy32(Output, m_InterStream.GetBuffer() + m_ReadPos, bytes_out);
- m_ReadPos += (FX_INT32)bytes_out;
- if (pcbRead != NULL) {
- *pcbRead = (ULONG)bytes_out;
- }
- return S_OK;
- }
- virtual HRESULT STDMETHODCALLTYPE Write(void const* Input, ULONG cb, ULONG* pcbWritten)
- {
- if (cb <= 0) {
- if (pcbWritten != NULL) {
- *pcbWritten = 0;
- }
- return S_OK;
- }
- m_InterStream.InsertBlock(m_InterStream.GetLength(), Input, cb);
- if (pcbWritten != NULL) {
- *pcbWritten = cb;
- }
- return S_OK;
- }
-public:
- virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE Commit(DWORD)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE Revert(void)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE Clone(IStream **)
- {
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, DWORD dwOrigin, ULARGE_INTEGER* lpNewFilePointer)
- {
- long start = 0;
- long new_read_position;
- switch(dwOrigin) {
- case STREAM_SEEK_SET:
- start = 0;
- break;
- case STREAM_SEEK_CUR:
- start = m_ReadPos;
- break;
- case STREAM_SEEK_END:
- start = m_InterStream.GetLength();
- break;
- default:
- return STG_E_INVALIDFUNCTION;
- break;
- }
- new_read_position = start + (long)liDistanceToMove.QuadPart;
- if (new_read_position < 0 || new_read_position > m_InterStream.GetLength()) {
- return STG_E_SEEKERROR;
- }
- m_ReadPos = new_read_position;
- if (lpNewFilePointer != NULL) {
- lpNewFilePointer->QuadPart = m_ReadPos;
- }
- return S_OK;
- }
- virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag)
- {
- if (pStatstg == NULL) {
- return STG_E_INVALIDFUNCTION;
- }
- ZeroMemory(pStatstg, sizeof(STATSTG));
- pStatstg->cbSize.QuadPart = m_InterStream.GetLength();
- return S_OK;
- }
-};
-typedef struct {
- BITMAPINFO* pbmi;
- int Stride;
- LPBYTE pScan0;
- GpBitmap* pBitmap;
- BitmapData* pBitmapData;
- GpStream* pStream;
-} PREVIEW3_DIBITMAP;
-static PREVIEW3_DIBITMAP* LoadDIBitmap(WINDIB_Open_Args_ args)
-{
- GpBitmap* pBitmap;
- GpStream* pStream = NULL;
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- Status status = Ok;
- if (args.flags == WINDIB_OPEN_PATHNAME) {
- status = CallFunc(GdipCreateBitmapFromFileICM)((wchar_t*)args.path_name, &pBitmap);
- } else {
- if (args.memory_size == 0 || !args.memory_base) {
- return NULL;
- }
- pStream = FX_NEW GpStream;
- if (!pStream) {
- return NULL;
- }
- pStream->Write(args.memory_base, (ULONG)args.memory_size, NULL);
- status = CallFunc(GdipCreateBitmapFromStreamICM)(pStream, &pBitmap);
- }
- if (status != Ok) {
- if (pStream) {
- pStream->Release();
- }
- return NULL;
- }
- UINT height, width;
- CallFunc(GdipGetImageHeight)(pBitmap, &height);
- CallFunc(GdipGetImageWidth)(pBitmap, &width);
- PixelFormat pixel_format;
- CallFunc(GdipGetImagePixelFormat)(pBitmap, &pixel_format);
- int info_size = sizeof(BITMAPINFOHEADER);
- int bpp = 24;
- int dest_pixel_format = PixelFormat24bppRGB;
- if (pixel_format == PixelFormat1bppIndexed) {
- info_size += 8;
- bpp = 1;
- dest_pixel_format = PixelFormat1bppIndexed;
- } else if (pixel_format == PixelFormat8bppIndexed) {
- info_size += 1024;
- bpp = 8;
- dest_pixel_format = PixelFormat8bppIndexed;
- } else if (pixel_format == PixelFormat32bppARGB) {
- bpp = 32;
- dest_pixel_format = PixelFormat32bppARGB;
- }
- LPBYTE buf = FX_Alloc(BYTE, info_size);
- if (!buf) {
- if (pStream) {
- pStream->Release();
- }
- return NULL;
- }
- BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)buf;
- FXSYS_memset32(buf, 0, info_size);
- pbmih->biBitCount = bpp;
- pbmih->biCompression = BI_RGB;
- pbmih->biHeight = -(int)height;
- pbmih->biPlanes = 1;
- pbmih->biWidth = width;
- Rect rect(0, 0, width, height);
- BitmapData* pBitmapData = FX_Alloc(BitmapData, 1);
- if (!pBitmapData) {
- if (pStream) {
- pStream->Release();
- }
- return NULL;
- }
- CallFunc(GdipBitmapLockBits)(pBitmap, &rect, ImageLockModeRead,
- dest_pixel_format, pBitmapData);
- if (pixel_format == PixelFormat1bppIndexed || pixel_format == PixelFormat8bppIndexed) {
- DWORD* ppal = (DWORD*)(buf + sizeof(BITMAPINFOHEADER));
- struct {
- UINT flags;
- UINT Count;
- DWORD Entries[256];
- } pal;
- int size = 0;
- CallFunc(GdipGetImagePaletteSize)(pBitmap, &size);
- CallFunc(GdipGetImagePalette)(pBitmap, (ColorPalette*)&pal, size);
- int entries = pixel_format == PixelFormat1bppIndexed ? 2 : 256;
- for (int i = 0; i < entries; i ++) {
- ppal[i] = pal.Entries[i] & 0x00ffffff;
- }
- }
- PREVIEW3_DIBITMAP* pInfo = FX_Alloc(PREVIEW3_DIBITMAP, 1);
- if (!pInfo) {
- if (pStream) {
- pStream->Release();
- }
- return NULL;
- }
- pInfo->pbmi = (BITMAPINFO*)buf;
- pInfo->pScan0 = (LPBYTE)pBitmapData->Scan0;
- pInfo->Stride = pBitmapData->Stride;
- pInfo->pBitmap = pBitmap;
- pInfo->pBitmapData = pBitmapData;
- pInfo->pStream = pStream;
- return pInfo;
-}
-static void FreeDIBitmap(PREVIEW3_DIBITMAP* pInfo)
-{
- CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
- CallFunc(GdipBitmapUnlockBits)(pInfo->pBitmap, pInfo->pBitmapData);
- CallFunc(GdipDisposeImage)(pInfo->pBitmap);
- FX_Free(pInfo->pBitmapData);
- FX_Free((LPBYTE)pInfo->pbmi);
- if (pInfo->pStream) {
- pInfo->pStream->Release();
- }
- FX_Free(pInfo);
-}
-CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha);
-CFX_DIBitmap* CGdiplusExt::LoadDIBitmap(WINDIB_Open_Args_ args)
-{
- PREVIEW3_DIBITMAP* pInfo = ::LoadDIBitmap(args);
- if (pInfo == NULL) {
- return NULL;
- }
- int height = abs(pInfo->pbmi->bmiHeader.biHeight);
- int width = pInfo->pbmi->bmiHeader.biWidth;
- int dest_pitch = (width * pInfo->pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
- LPBYTE pData = FX_Alloc(BYTE, dest_pitch * height);
- if (pData == NULL) {
- FreeDIBitmap(pInfo);
- return NULL;
- }
- if (dest_pitch == pInfo->Stride) {
- FXSYS_memcpy32(pData, pInfo->pScan0, dest_pitch * height);
- } else for (int i = 0; i < height; i ++) {
- FXSYS_memcpy32(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, dest_pitch);
- }
- CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf(pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32);
- FX_Free(pData);
- FreeDIBitmap(pInfo);
- return pDIBitmap;
-}
-#endif
+// 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 "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include <windows.h>
+#include "../../../include/fxge/fx_ge_win32.h"
+#include "win32_int.h"
+#include "../Microsoft SDK/include/GdiPlus.h"
+using namespace Gdiplus;
+using namespace Gdiplus::DllExports;
+#define GdiFillType2Gdip(fill_type) (fill_type == ALTERNATE ? FillModeAlternate : FillModeWinding)
+static CombineMode GdiCombineMode2Gdip(int mode)
+{
+ switch (mode) {
+ case RGN_AND:
+ return CombineModeIntersect;
+ }
+ return CombineModeIntersect;
+}
+enum {
+ FuncId_GdipCreatePath2,
+ FuncId_GdipSetPenDashStyle,
+ FuncId_GdipSetPenDashArray,
+ FuncId_GdipSetPenDashCap197819,
+ FuncId_GdipSetPenLineJoin,
+ FuncId_GdipSetPenWidth,
+ FuncId_GdipCreateFromHDC,
+ FuncId_GdipSetPageUnit,
+ FuncId_GdipSetSmoothingMode,
+ FuncId_GdipCreateSolidFill,
+ FuncId_GdipFillPath,
+ FuncId_GdipDeleteBrush,
+ FuncId_GdipCreatePen1,
+ FuncId_GdipSetPenMiterLimit,
+ FuncId_GdipDrawPath,
+ FuncId_GdipDeletePen,
+ FuncId_GdipDeletePath,
+ FuncId_GdipDeleteGraphics,
+ FuncId_GdipCreateBitmapFromFileICM,
+ FuncId_GdipCreateBitmapFromStreamICM,
+ FuncId_GdipGetImageHeight,
+ FuncId_GdipGetImageWidth,
+ FuncId_GdipGetImagePixelFormat,
+ FuncId_GdipBitmapLockBits,
+ FuncId_GdipGetImagePaletteSize,
+ FuncId_GdipGetImagePalette,
+ FuncId_GdipBitmapUnlockBits,
+ FuncId_GdipDisposeImage,
+ FuncId_GdipFillRectangle,
+ FuncId_GdipCreateBitmapFromScan0,
+ FuncId_GdipSetImagePalette,
+ FuncId_GdipSetInterpolationMode,
+ FuncId_GdipDrawImagePointsI,
+ FuncId_GdipCreateBitmapFromGdiDib,
+ FuncId_GdiplusStartup,
+ FuncId_GdipDrawLineI,
+ FuncId_GdipResetClip,
+ FuncId_GdipCreatePath,
+ FuncId_GdipAddPathPath,
+ FuncId_GdipSetPathFillMode,
+ FuncId_GdipSetClipPath,
+ FuncId_GdipGetClip,
+ FuncId_GdipCreateRegion,
+ FuncId_GdipGetClipBoundsI,
+ FuncId_GdipSetClipRegion,
+ FuncId_GdipWidenPath,
+ FuncId_GdipAddPathLine,
+ FuncId_GdipAddPathRectangle,
+ FuncId_GdipDeleteRegion,
+ FuncId_GdipGetDC,
+ FuncId_GdipReleaseDC,
+ FuncId_GdipSetPenLineCap197819,
+ FuncId_GdipSetPenDashOffset,
+ FuncId_GdipResetPath,
+ FuncId_GdipCreateRegionPath,
+ FuncId_GdipCreateFont,
+ FuncId_GdipGetFontSize,
+ FuncId_GdipCreateFontFamilyFromName,
+ FuncId_GdipSetTextRenderingHint,
+ FuncId_GdipDrawDriverString,
+ FuncId_GdipCreateMatrix2,
+ FuncId_GdipDeleteMatrix,
+ FuncId_GdipSetWorldTransform,
+ FuncId_GdipResetWorldTransform,
+ FuncId_GdipDeleteFontFamily,
+ FuncId_GdipDeleteFont,
+ FuncId_GdipNewPrivateFontCollection,
+ FuncId_GdipDeletePrivateFontCollection,
+ FuncId_GdipPrivateAddMemoryFont,
+ FuncId_GdipGetFontCollectionFamilyList,
+ FuncId_GdipGetFontCollectionFamilyCount,
+ FuncId_GdipSetTextContrast,
+ FuncId_GdipSetPixelOffsetMode,
+ FuncId_GdipGetImageGraphicsContext,
+ FuncId_GdipDrawImageI,
+ FuncId_GdipDrawImageRectI,
+ FuncId_GdipDrawString,
+ FuncId_GdipSetPenTransform,
+};
+static LPCSTR g_GdipFuncNames[] = {
+ "GdipCreatePath2",
+ "GdipSetPenDashStyle",
+ "GdipSetPenDashArray",
+ "GdipSetPenDashCap197819",
+ "GdipSetPenLineJoin",
+ "GdipSetPenWidth",
+ "GdipCreateFromHDC",
+ "GdipSetPageUnit",
+ "GdipSetSmoothingMode",
+ "GdipCreateSolidFill",
+ "GdipFillPath",
+ "GdipDeleteBrush",
+ "GdipCreatePen1",
+ "GdipSetPenMiterLimit",
+ "GdipDrawPath",
+ "GdipDeletePen",
+ "GdipDeletePath",
+ "GdipDeleteGraphics",
+ "GdipCreateBitmapFromFileICM",
+ "GdipCreateBitmapFromStreamICM",
+ "GdipGetImageHeight",
+ "GdipGetImageWidth",
+ "GdipGetImagePixelFormat",
+ "GdipBitmapLockBits",
+ "GdipGetImagePaletteSize",
+ "GdipGetImagePalette",
+ "GdipBitmapUnlockBits",
+ "GdipDisposeImage",
+ "GdipFillRectangle",
+ "GdipCreateBitmapFromScan0",
+ "GdipSetImagePalette",
+ "GdipSetInterpolationMode",
+ "GdipDrawImagePointsI",
+ "GdipCreateBitmapFromGdiDib",
+ "GdiplusStartup",
+ "GdipDrawLineI",
+ "GdipResetClip",
+ "GdipCreatePath",
+ "GdipAddPathPath",
+ "GdipSetPathFillMode",
+ "GdipSetClipPath",
+ "GdipGetClip",
+ "GdipCreateRegion",
+ "GdipGetClipBoundsI",
+ "GdipSetClipRegion",
+ "GdipWidenPath",
+ "GdipAddPathLine",
+ "GdipAddPathRectangle",
+ "GdipDeleteRegion",
+ "GdipGetDC",
+ "GdipReleaseDC",
+ "GdipSetPenLineCap197819",
+ "GdipSetPenDashOffset",
+ "GdipResetPath",
+ "GdipCreateRegionPath",
+ "GdipCreateFont",
+ "GdipGetFontSize",
+ "GdipCreateFontFamilyFromName",
+ "GdipSetTextRenderingHint",
+ "GdipDrawDriverString",
+ "GdipCreateMatrix2",
+ "GdipDeleteMatrix",
+ "GdipSetWorldTransform",
+ "GdipResetWorldTransform",
+ "GdipDeleteFontFamily",
+ "GdipDeleteFont",
+ "GdipNewPrivateFontCollection",
+ "GdipDeletePrivateFontCollection",
+ "GdipPrivateAddMemoryFont",
+ "GdipGetFontCollectionFamilyList",
+ "GdipGetFontCollectionFamilyCount",
+ "GdipSetTextContrast",
+ "GdipSetPixelOffsetMode",
+ "GdipGetImageGraphicsContext",
+ "GdipDrawImageI",
+ "GdipDrawImageRectI",
+ "GdipDrawString",
+ "GdipSetPenTransform",
+};
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath2)(GDIPCONST GpPointF*, GDIPCONST BYTE*, INT, GpFillMode, GpPath **path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashStyle)(GpPen *pen, GpDashStyle dashstyle);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashArray)(GpPen *pen, GDIPCONST REAL *dash, INT count);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashCap197819)(GpPen *pen, GpDashCap dashCap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineJoin)(GpPen *pen, GpLineJoin lineJoin);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenWidth)(GpPen *pen, REAL width);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFromHDC)(HDC hdc, GpGraphics **graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPageUnit)(GpGraphics *graphics, GpUnit unit);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetSmoothingMode)(GpGraphics *graphics, SmoothingMode smoothingMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateSolidFill)(ARGB color, GpSolidFill **brush);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipFillPath)(GpGraphics *graphics, GpBrush *brush, GpPath *path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteBrush)(GpBrush *brush);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePen1)(ARGB color, REAL width, GpUnit unit, GpPen **pen);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenMiterLimit)(GpPen *pen, REAL miterLimit);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawPath)(GpGraphics *graphics, GpPen *pen, GpPath *path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePen)(GpPen *pen);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePath)(GpPath* path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteGraphics)(GpGraphics *graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromFileICM)(GDIPCONST WCHAR* filename, GpBitmap **bitmap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromStreamICM)(IStream* stream, GpBitmap **bitmap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageWidth)(GpImage *image, UINT *width);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageHeight)(GpImage *image, UINT *height);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePixelFormat)(GpImage *image, PixelFormat *format);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapLockBits)(GpBitmap* bitmap, GDIPCONST GpRect* rect, UINT flags, PixelFormat format, BitmapData* lockedBitmapData);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePalette)(GpImage *image, ColorPalette *palette, INT size);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImagePaletteSize)(GpImage *image, INT *size);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipBitmapUnlockBits)(GpBitmap* bitmap, BitmapData* lockedBitmapData);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDisposeImage)(GpImage *image);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipFillRectangle)(GpGraphics *graphics, GpBrush *brush, REAL x, REAL y, REAL width, REAL height);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromScan0)(INT width, INT height, INT stride, PixelFormat format, BYTE* scan0, GpBitmap** bitmap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetImagePalette)(GpImage *image, GDIPCONST ColorPalette *palette);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetInterpolationMode)(GpGraphics *graphics, InterpolationMode interpolationMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImagePointsI)(GpGraphics *graphics, GpImage *image, GDIPCONST GpPoint *dstpoints, INT count);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateBitmapFromGdiDib)(GDIPCONST BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData, GpBitmap** bitmap);
+typedef Status (WINAPI *FuncType_GdiplusStartup)(OUT FX_UINTPTR *token, const GdiplusStartupInput *input, OUT GdiplusStartupOutput *output);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawLineI)(GpGraphics *graphics, GpPen *pen, int x1, int y1, int x2, int y2);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipResetClip)(GpGraphics *graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreatePath)(GpFillMode brushMode, GpPath **path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathPath)(GpPath *path, GDIPCONST GpPath* addingPath, BOOL connect);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPathFillMode)(GpPath *path, GpFillMode fillmode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipPath)(GpGraphics *graphics, GpPath *path, CombineMode combineMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClip)(GpGraphics *graphics, GpRegion *region);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegion)(GpRegion **region);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetClipBoundsI)(GpGraphics *graphics, GpRect *rect);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetClipRegion)(GpGraphics *graphics, GpRegion *region, CombineMode combineMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipWidenPath)(GpPath *nativePath, GpPen *pen, GpMatrix *matrix, REAL flatness);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathLine)(GpPath *path, REAL x1, REAL y1, REAL x2, REAL y2);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipAddPathRectangle)(GpPath *path, REAL x, REAL y, REAL width, REAL height);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteRegion)(GpRegion *region);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetDC)(GpGraphics* graphics, HDC * hdc);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipReleaseDC)(GpGraphics* graphics, HDC hdc);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenLineCap197819)(GpPen *pen, GpLineCap startCap, GpLineCap endCap, GpDashCap dashCap);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenDashOffset)(GpPen *pen, REAL offset);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipResetPath)(GpPath *path);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateRegionPath)(GpPath *path, GpRegion **region);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFont)(GDIPCONST GpFontFamily *fontFamily, REAL emSize, INT style, Unit unit, GpFont **font);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontSize)(GpFont *font, REAL *size);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateFontFamilyFromName)(GDIPCONST WCHAR *name, GpFontCollection *fontCollection, GpFontFamily **FontFamily);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextRenderingHint)(GpGraphics *graphics, TextRenderingHint mode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawDriverString)(GpGraphics *graphics, GDIPCONST UINT16 *text, INT length, GDIPCONST GpFont *font, GDIPCONST GpBrush *brush, GDIPCONST PointF *positions, INT flags, GDIPCONST GpMatrix *matrix);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipCreateMatrix2)(REAL m11, REAL m12, REAL m21, REAL m22, REAL dx, REAL dy, GpMatrix **matrix);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteMatrix)(GpMatrix *matrix);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetWorldTransform)(GpGraphics *graphics, GpMatrix *matrix);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipResetWorldTransform)(GpGraphics *graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFontFamily)(GpFontFamily *FontFamily);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeleteFont)(GpFont* font);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipNewPrivateFontCollection)(GpFontCollection** fontCollection);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDeletePrivateFontCollection)(GpFontCollection** fontCollection);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipPrivateAddMemoryFont)(GpFontCollection* fontCollection, GDIPCONST void* memory, INT length);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyList)(GpFontCollection* fontCollection, INT numSought, GpFontFamily* gpfamilies[], INT* numFound);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetFontCollectionFamilyCount)(GpFontCollection* fontCollection, INT* numFound);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetTextContrast)(GpGraphics *graphics, UINT contrast);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPixelOffsetMode)(GpGraphics* graphics, PixelOffsetMode pixelOffsetMode);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipGetImageGraphicsContext)(GpImage *image, GpGraphics **graphics);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageI)(GpGraphics *graphics, GpImage *image, INT x, INT y);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawImageRectI)(GpGraphics *graphics, GpImage *image, INT x, INT y, INT width, INT height);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipDrawString)(GpGraphics *graphics, GDIPCONST WCHAR *string, INT length, GDIPCONST GpFont *font, GDIPCONST RectF *layoutRect, GDIPCONST GpStringFormat *stringFormat, GDIPCONST GpBrush *brush);
+typedef GpStatus (WINGDIPAPI *FuncType_GdipSetPenTransform)(GpPen *pen, GpMatrix *matrix);
+#define CallFunc(funcname) ((FuncType_##funcname)GdiplusExt.m_Functions[FuncId_##funcname])
+typedef HANDLE (__stdcall *FuncType_GdiAddFontMemResourceEx)(PVOID pbFont, DWORD cbFont, PVOID pdv, DWORD *pcFonts);
+typedef BOOL (__stdcall *FuncType_GdiRemoveFontMemResourceEx)(HANDLE handle);
+void* CGdiplusExt::GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face)
+{
+ if (m_pGdiAddFontMemResourceEx) {
+ return ((FuncType_GdiAddFontMemResourceEx)m_pGdiAddFontMemResourceEx)((PVOID)pFontdata, (DWORD)size, (PVOID)pdv, (DWORD*)num_face);
+ }
+ return NULL;
+}
+FX_BOOL CGdiplusExt::GdiRemoveFontMemResourceEx(void* handle)
+{
+ if (m_pGdiRemoveFontMemResourseEx) {
+ return ((FuncType_GdiRemoveFontMemResourceEx)m_pGdiRemoveFontMemResourseEx)((HANDLE)handle);
+ }
+ return FALSE;
+}
+static GpBrush* _GdipCreateBrush(DWORD argb)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpSolidFill* solidBrush = NULL;
+ CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
+ return solidBrush;
+}
+static CFX_DIBitmap* _StretchMonoToGray(int dest_width, int dest_height,
+ const CFX_DIBitmap* pSource, FX_RECT* pClipRect)
+{
+ FX_BOOL bFlipX = dest_width < 0;
+ if (bFlipX) {
+ dest_width = -dest_width;
+ }
+ FX_BOOL bFlipY = dest_height < 0;
+ if (bFlipY) {
+ dest_height = -dest_height;
+ }
+ int result_width = pClipRect->Width();
+ int result_height = pClipRect->Height();
+ int result_pitch = (result_width + 3) / 4 * 4;
+ CFX_DIBitmap* pStretched = FX_NEW CFX_DIBitmap;
+ if (!pStretched) {
+ return NULL;
+ }
+ if (!pStretched->Create(result_width, result_height, FXDIB_8bppRgb)) {
+ delete pStretched;
+ return NULL;
+ }
+ LPBYTE dest_buf = pStretched->GetBuffer();
+ int src_width = pSource->GetWidth();
+ int src_height = pSource->GetHeight();
+ int src_count = src_width * src_height;
+ int dest_count = dest_width * dest_height;
+ int ratio = 255 * dest_count / src_count;
+ int y_unit = src_height / dest_height;
+ int x_unit = src_width / dest_width;
+ int area_unit = y_unit * x_unit;
+ LPBYTE src_buf = pSource->GetBuffer();
+ int src_pitch = pSource->GetPitch();
+ for (int dest_y = 0; dest_y < result_height; dest_y ++) {
+ LPBYTE dest_scan = dest_buf + dest_y * result_pitch;
+ int src_y_start = bFlipY ? (dest_height - 1 - dest_y - pClipRect->top) : (dest_y + pClipRect->top);
+ src_y_start = src_y_start * src_height / dest_height;
+ LPBYTE src_scan = src_buf + src_y_start * src_pitch;
+ for (int dest_x = 0; dest_x < result_width; dest_x ++) {
+ int sum = 0;
+ int src_x_start = bFlipX ? (dest_width - 1 - dest_x - pClipRect->left) : (dest_x + pClipRect->left);
+ src_x_start = src_x_start * src_width / dest_width;
+ int src_x_end = src_x_start + x_unit;
+ LPBYTE src_line = src_scan;
+ for (int src_y = 0; src_y < y_unit; src_y ++) {
+ for (int src_x = src_x_start; src_x < src_x_end; src_x ++) {
+ if (!(src_line[src_x / 8] & (1 << (7 - src_x % 8)))) {
+ sum += 255;
+ }
+ }
+ src_line += src_pitch;
+ }
+ dest_scan[dest_x] = 255 - sum / area_unit;
+ }
+ }
+ return pStretched;
+}
+static void OutputImageMask(GpGraphics* pGraphics, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_ARGB argb, const FX_RECT* pClipRect)
+{
+ ASSERT(pBitmap->GetBPP() == 1);
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ int src_width = pBitmap->GetWidth(), src_height = pBitmap->GetHeight();
+ int src_pitch = pBitmap->GetPitch();
+ FX_LPBYTE scan0 = pBitmap->GetBuffer();
+ if (src_width == 1 && src_height == 1) {
+ if ((scan0[0] & 0x80) == 0) {
+ return;
+ }
+ GpSolidFill* solidBrush;
+ CallFunc(GdipCreateSolidFill)((ARGB)argb, &solidBrush);
+ if (dest_width < 0) {
+ dest_width = -dest_width;
+ dest_left -= dest_width;
+ }
+ if (dest_height < 0) {
+ dest_height = -dest_height;
+ dest_top -= dest_height;
+ }
+ CallFunc(GdipFillRectangle)(pGraphics, solidBrush, (float)dest_left, (float)dest_top,
+ (float)dest_width, (float)dest_height);
+ CallFunc(GdipDeleteBrush)(solidBrush);
+ return;
+ }
+ if (!bMonoDevice && abs(dest_width) < src_width && abs(dest_height) < src_height) {
+ FX_RECT image_rect(dest_left, dest_top, dest_left + dest_width, dest_top + dest_height);
+ image_rect.Normalize();
+ FX_RECT image_clip = image_rect;
+ image_clip.Intersect(*pClipRect);
+ if (image_clip.IsEmpty()) {
+ return;
+ }
+ image_clip.Offset(-image_rect.left, -image_rect.top);
+ CFX_DIBitmap* pStretched = NULL;
+ if (src_width * src_height > 10000) {
+ pStretched = _StretchMonoToGray(dest_width, dest_height, pBitmap, &image_clip);
+ } else {
+ pStretched = pBitmap->StretchTo(dest_width, dest_height, FALSE, &image_clip);
+ }
+ GpBitmap* bitmap;
+ CallFunc(GdipCreateBitmapFromScan0)(image_clip.Width(), image_clip.Height(),
+ (image_clip.Width() + 3) / 4 * 4, PixelFormat8bppIndexed, pStretched->GetBuffer(), &bitmap);
+ int a, r, g, b;
+ ArgbDecode(argb, a, r, g, b);
+ UINT pal[258];
+ pal[0] = 0;
+ pal[1] = 256;
+ for (int i = 0; i < 256; i ++) {
+ pal[i + 2] = ArgbEncode(i * a / 255, r, g, b);
+ }
+ CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
+ CallFunc(GdipDrawImageI)(pGraphics, bitmap, image_rect.left + image_clip.left,
+ image_rect.top + image_clip.top);
+ CallFunc(GdipDisposeImage)(bitmap);
+ delete pStretched;
+ return;
+ }
+ GpBitmap* bitmap;
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch, PixelFormat1bppIndexed, scan0, &bitmap);
+ UINT palette[4] = { PaletteFlagsHasAlpha, 2, 0, argb };
+ CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)palette);
+ Point destinationPoints[] = {
+ Point(dest_left, dest_top),
+ Point(dest_left + dest_width, dest_top),
+ Point(dest_left, dest_top + dest_height)
+ };
+ CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
+ CallFunc(GdipDisposeImage)(bitmap);
+}
+static void OutputImage(GpGraphics* pGraphics, const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect,
+ int dest_left, int dest_top, int dest_width, int dest_height)
+{
+ int src_width = pSrcRect->Width(), src_height = pSrcRect->Height();
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ if (pBitmap->GetBPP() == 1 && (pSrcRect->left % 8)) {
+ FX_RECT new_rect(0, 0, src_width, src_height);
+ CFX_DIBitmap* pCloned = pBitmap->Clone(pSrcRect);
+ if (!pCloned) {
+ return;
+ }
+ OutputImage(pGraphics, pCloned, &new_rect, dest_left, dest_top, dest_width, dest_height);
+ delete pCloned;
+ return;
+ }
+ int src_pitch = pBitmap->GetPitch();
+ FX_LPBYTE scan0 = pBitmap->GetBuffer() + pSrcRect->top * src_pitch + pBitmap->GetBPP() * pSrcRect->left / 8;
+ GpBitmap* bitmap = NULL;
+ switch (pBitmap->GetFormat()) {
+ case FXDIB_Argb:
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat32bppARGB, scan0, &bitmap);
+ break;
+ case FXDIB_Rgb32:
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat32bppRGB, scan0, &bitmap);
+ break;
+ case FXDIB_Rgb:
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat24bppRGB, scan0, &bitmap);
+ break;
+ case FXDIB_8bppRgb: {
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat8bppIndexed, scan0, &bitmap);
+ UINT pal[258];
+ pal[0] = 0;
+ pal[1] = 256;
+ for (int i = 0; i < 256; i ++) {
+ pal[i + 2] = pBitmap->GetPaletteEntry(i);
+ }
+ CallFunc(GdipSetImagePalette)(bitmap, (ColorPalette*)pal);
+ break;
+ }
+ case FXDIB_1bppRgb: {
+ CallFunc(GdipCreateBitmapFromScan0)(src_width, src_height, src_pitch,
+ PixelFormat1bppIndexed, scan0, &bitmap);
+ break;
+ }
+ }
+ if (dest_height < 0) {
+ dest_height --;
+ }
+ if (dest_width < 0) {
+ dest_width --;
+ }
+ Point destinationPoints[] = {
+ Point(dest_left, dest_top),
+ Point(dest_left + dest_width, dest_top),
+ Point(dest_left, dest_top + dest_height)
+ };
+ CallFunc(GdipDrawImagePointsI)(pGraphics, bitmap, destinationPoints, 3);
+ CallFunc(GdipDisposeImage)(bitmap);
+}
+CGdiplusExt::CGdiplusExt()
+{
+ m_hModule = NULL;
+ m_GdiModule = NULL;
+ for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
+ m_Functions[i] = NULL;
+ }
+ m_pGdiAddFontMemResourceEx = NULL;
+ m_pGdiRemoveFontMemResourseEx = NULL;
+}
+void CGdiplusExt::Load()
+{
+ CFX_ByteString strPlusPath = "";
+ FX_CHAR buf[MAX_PATH];
+ GetSystemDirectoryA(buf, MAX_PATH);
+ strPlusPath += buf;
+ strPlusPath += "\\";
+ strPlusPath += "GDIPLUS.DLL";
+ m_hModule = LoadLibraryA(strPlusPath);
+ if (m_hModule == NULL) {
+ return;
+ }
+ for (int i = 0; i < sizeof g_GdipFuncNames / sizeof(LPCSTR); i ++) {
+ m_Functions[i] = GetProcAddress(m_hModule, g_GdipFuncNames[i]);
+ if (m_Functions[i] == NULL) {
+ m_hModule = NULL;
+ return;
+ }
+ }
+ FX_UINTPTR gdiplusToken;
+ GdiplusStartupInput gdiplusStartupInput;
+ ((FuncType_GdiplusStartup)m_Functions[FuncId_GdiplusStartup])(&gdiplusToken, &gdiplusStartupInput, NULL);
+ m_GdiModule = LoadLibraryA("GDI32.DLL");
+ if (m_GdiModule == NULL) {
+ return;
+ }
+ m_pGdiAddFontMemResourceEx = GetProcAddress(m_GdiModule, "AddFontMemResourceEx");
+ m_pGdiRemoveFontMemResourseEx = GetProcAddress(m_GdiModule, "RemoveFontMemResourceEx");
+}
+CGdiplusExt::~CGdiplusExt()
+{
+}
+LPVOID CGdiplusExt::LoadMemFont(LPBYTE pData, FX_DWORD size)
+{
+ GpFontCollection* pCollection = NULL;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipNewPrivateFontCollection)(&pCollection);
+ GpStatus status = CallFunc(GdipPrivateAddMemoryFont)(pCollection, pData, size);
+ if (status == Ok) {
+ return pCollection;
+ }
+ CallFunc(GdipDeletePrivateFontCollection)(&pCollection);
+ return NULL;
+}
+void CGdiplusExt::DeleteMemFont(LPVOID pCollection)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeletePrivateFontCollection)((GpFontCollection**)&pCollection);
+}
+FX_BOOL CGdiplusExt::GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ PixelFormat format;
+ switch (pBitmap->GetFormat()) {
+ case FXDIB_Rgb:
+ format = PixelFormat24bppRGB;
+ break;
+ case FXDIB_Rgb32:
+ format = PixelFormat32bppRGB;
+ break;
+ case FXDIB_Argb:
+ format = PixelFormat32bppARGB;
+ break;
+ default:
+ return FALSE;
+ }
+ GpStatus status = CallFunc(GdipCreateBitmapFromScan0)(pBitmap->GetWidth(), pBitmap->GetHeight(),
+ pBitmap->GetPitch(), format, pBitmap->GetBuffer(), (GpBitmap**)bitmap);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CGdiplusExt::GdipCreateFromImage(void* bitmap, void** graphics)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipGetImageGraphicsContext)((GpBitmap*)bitmap, (GpGraphics**)graphics);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CGdiplusExt::GdipCreateFontFamilyFromName(FX_LPCWSTR name, void* pFontCollection, void**pFamily)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipCreateFontFamilyFromName)((GDIPCONST WCHAR *)name, (GpFontCollection*)pFontCollection, (GpFontFamily**)pFamily);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+FX_BOOL CGdiplusExt::GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipCreateFont)((GpFontFamily*)pFamily, font_size, fontstyle, Unit(flag), (GpFont**)pFont);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+void CGdiplusExt::GdipGetFontSize(void *pFont, FX_FLOAT *size)
+{
+ REAL get_size;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipGetFontSize)((GpFont *)pFont, (REAL*)&get_size);
+ if (status == Ok) {
+ *size = (FX_FLOAT)get_size;
+ } else {
+ *size = 0;
+ }
+}
+void CGdiplusExt::GdipSetTextRenderingHint(void* graphics, int mode)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipSetTextRenderingHint)((GpGraphics*)graphics, (TextRenderingHint)mode);
+}
+void CGdiplusExt::GdipSetPageUnit(void* graphics, FX_DWORD unit)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipSetPageUnit)((GpGraphics*)graphics, (GpUnit)unit);
+}
+FX_BOOL CGdiplusExt::GdipDrawDriverString(void *graphics, unsigned short *text, int length,
+ void *font, void* brush, void *positions, int flags, const void *matrix)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpStatus status = CallFunc(GdipDrawDriverString)((GpGraphics*)graphics, (GDIPCONST UINT16 *)text, (INT)length, (GDIPCONST GpFont *)font, (GDIPCONST GpBrush*)brush,
+ (GDIPCONST PointF *)positions, (INT)flags, (GDIPCONST GpMatrix *)matrix);
+ if (status == Ok) {
+ return TRUE;
+ }
+ return FALSE;
+}
+void CGdiplusExt::GdipCreateBrush(FX_DWORD fill_argb, void** pBrush)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipCreateSolidFill)((ARGB)fill_argb, (GpSolidFill**)pBrush);
+}
+void CGdiplusExt::GdipDeleteBrush(void* pBrush)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteBrush)((GpSolidFill*)pBrush);
+}
+void* CGdiplusExt::GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ int numFamilies = 0;
+ GpStatus status = CallFunc(GdipGetFontCollectionFamilyCount)((GpFontCollection*)pFontCollection, &numFamilies);
+ if (status != Ok) {
+ return NULL;
+ }
+ GpFontFamily* family_list[1];
+ status = CallFunc(GdipGetFontCollectionFamilyList)((GpFontCollection*)pFontCollection, 1, family_list, &numFamilies);
+ if (status != Ok) {
+ return NULL;
+ }
+ GpFont* pFont = NULL;
+ status = CallFunc(GdipCreateFont)(family_list[0], font_size, fontstyle, UnitPixel, &pFont);
+ if (status != Ok) {
+ return NULL;
+ }
+ return pFont;
+}
+void CGdiplusExt::GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipCreateMatrix2)(a, b, c, d, e, f, (GpMatrix**)matrix);
+}
+void CGdiplusExt::GdipDeleteMatrix(void* matrix)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteMatrix)((GpMatrix*)matrix);
+}
+void CGdiplusExt::GdipDeleteFontFamily(void* pFamily)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteFontFamily)((GpFontFamily*)pFamily);
+}
+void CGdiplusExt::GdipDeleteFont(void* pFont)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteFont)((GpFont*)pFont);
+}
+void CGdiplusExt::GdipSetWorldTransform(void* graphics, void* pMatrix)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipSetWorldTransform)((GpGraphics*)graphics, (GpMatrix*)pMatrix);
+}
+void CGdiplusExt::GdipDisposeImage(void* bitmap)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDisposeImage)((GpBitmap*)bitmap);
+}
+void CGdiplusExt::GdipDeleteGraphics(void* graphics)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipDeleteGraphics)((GpGraphics*)graphics);
+}
+FX_BOOL CGdiplusExt::StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags)
+{
+ ASSERT(pBitmap->GetBPP() == 1);
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ GpGraphics* pGraphics = NULL;
+ CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
+ CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
+ if (flags & FXDIB_NOSMOOTH) {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor);
+ } else {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
+ }
+ OutputImageMask(pGraphics, bMonoDevice, pBitmap, dest_left, dest_top, dest_width, dest_height, argb, pClipRect);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ return TRUE;
+}
+FX_BOOL CGdiplusExt::StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, int flags)
+{
+ GpGraphics* pGraphics;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
+ CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
+ if (flags & FXDIB_NOSMOOTH) {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeNearestNeighbor);
+ } else if (pBitmap->GetWidth() > abs(dest_width) / 2 || pBitmap->GetHeight() > abs(dest_height) / 2) {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeHighQuality);
+ } else {
+ CallFunc(GdipSetInterpolationMode)(pGraphics, InterpolationModeBilinear);
+ }
+ FX_RECT src_rect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
+ OutputImage(pGraphics, pBitmap, &src_rect, dest_left, dest_top, dest_width, dest_height);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ return TRUE;
+}
+static GpPen* _GdipCreatePen(const CFX_GraphStateData* pGraphState, const CFX_AffineMatrix* pMatrix, DWORD argb, FX_BOOL bTextMode = FALSE)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ FX_FLOAT width = pGraphState ? pGraphState->m_LineWidth : 1.0f;
+ if (!bTextMode) {
+ FX_FLOAT unit = pMatrix == NULL ? 1.0f : FXSYS_Div(1.0f, (pMatrix->GetXUnit() + pMatrix->GetYUnit()) / 2);
+ if (width < unit) {
+ width = unit;
+ }
+ }
+ GpPen* pPen = NULL;
+ CallFunc(GdipCreatePen1)((ARGB)argb, width, UnitWorld, &pPen);
+ LineCap lineCap;
+ DashCap dashCap = DashCapFlat;
+ FX_BOOL bDashExtend = FALSE;
+ switch(pGraphState->m_LineCap) {
+ case CFX_GraphStateData::LineCapButt:
+ lineCap = LineCapFlat;
+ break;
+ case CFX_GraphStateData::LineCapRound:
+ lineCap = LineCapRound;
+ dashCap = DashCapRound;
+ bDashExtend = TRUE;
+ break;
+ case CFX_GraphStateData::LineCapSquare:
+ lineCap = LineCapSquare;
+ bDashExtend = TRUE;
+ break;
+ }
+ CallFunc(GdipSetPenLineCap197819)(pPen, lineCap, lineCap, dashCap);
+ LineJoin lineJoin;
+ switch(pGraphState->m_LineJoin) {
+ case CFX_GraphStateData::LineJoinMiter:
+ lineJoin = LineJoinMiterClipped;
+ break;
+ case CFX_GraphStateData::LineJoinRound:
+ lineJoin = LineJoinRound;
+ break;
+ case CFX_GraphStateData::LineJoinBevel:
+ lineJoin = LineJoinBevel;
+ break;
+ }
+ CallFunc(GdipSetPenLineJoin)(pPen, lineJoin);
+ if(pGraphState->m_DashCount) {
+ FX_FLOAT* pDashArray = FX_Alloc(FX_FLOAT, pGraphState->m_DashCount + pGraphState->m_DashCount % 2);
+ if (!pDashArray) {
+ return NULL;
+ }
+ int nCount = 0;
+ FX_FLOAT on_leftover = 0, off_leftover = 0;
+ for (int i = 0; i < pGraphState->m_DashCount; i += 2) {
+ FX_FLOAT on_phase = pGraphState->m_DashArray[i];
+ FX_FLOAT off_phase;
+ if (i == pGraphState->m_DashCount - 1) {
+ off_phase = on_phase;
+ } else {
+ off_phase = pGraphState->m_DashArray[i + 1];
+ }
+ on_phase /= width;
+ off_phase /= width;
+ if (on_phase + off_phase <= 0.00002f) {
+ on_phase = 1.0f / 10;
+ off_phase = 1.0f / 10;
+ }
+ if (bDashExtend) {
+ if (off_phase < 1) {
+ off_phase = 0;
+ } else {
+ off_phase -= 1;
+ }
+ on_phase += 1;
+ }
+ if (on_phase == 0 || off_phase == 0) {
+ if (nCount == 0) {
+ on_leftover += on_phase;
+ off_leftover += off_phase;
+ } else {
+ pDashArray[nCount - 2] += on_phase;
+ pDashArray[nCount - 1] += off_phase;
+ }
+ } else {
+ pDashArray[nCount++] = on_phase + on_leftover;
+ on_leftover = 0;
+ pDashArray[nCount++] = off_phase + off_leftover;
+ off_leftover = 0;
+ }
+ }
+ CallFunc(GdipSetPenDashArray)(pPen, pDashArray, nCount);
+ FX_FLOAT phase = pGraphState->m_DashPhase;
+ if (bDashExtend)
+ if (phase < 0.5f) {
+ phase = 0;
+ } else {
+ phase -= 0.5f;
+ }
+ CallFunc(GdipSetPenDashOffset)(pPen, phase);
+ FX_Free(pDashArray);
+ pDashArray = NULL;
+ }
+ CallFunc(GdipSetPenMiterLimit)(pPen, pGraphState->m_MiterLimit);
+ return pPen;
+}
+static BOOL IsSmallTriangle(PointF* points, const CFX_AffineMatrix* pMatrix, int& v1, int& v2)
+{
+ int pairs[] = {1, 2, 0, 2, 0, 1};
+ for (int i = 0; i < 3; i ++) {
+ int pair1 = pairs[i * 2];
+ int pair2 = pairs[i * 2 + 1];
+ FX_FLOAT x1 = points[pair1].X, x2 = points[pair2].X;
+ FX_FLOAT y1 = points[pair1].Y, y2 = points[pair2].Y;
+ if (pMatrix) {
+ pMatrix->Transform(x1, y1);
+ pMatrix->Transform(x2, y2);
+ }
+ FX_FLOAT dx = x1 - x2;
+ FX_FLOAT dy = y1 - y2;
+ FX_FLOAT distance_square = FXSYS_Mul(dx, dx) + FXSYS_Mul(dy, dy);
+ if (distance_square < (1.0f * 2 + 1.0f / 4)) {
+ v1 = i;
+ v2 = pair1;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+BOOL CGdiplusExt::DrawPath(HDC hDC, const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_argb,
+ FX_DWORD stroke_argb,
+ int fill_mode
+ )
+{
+ int nPoints = pPathData->GetPointCount();
+ if (nPoints == 0) {
+ return TRUE;
+ }
+ FX_PATHPOINT* pPoints = pPathData->GetPoints();
+ GpGraphics* pGraphics = NULL;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipCreateFromHDC)(hDC, &pGraphics);
+ CallFunc(GdipSetPageUnit)(pGraphics, UnitPixel);
+ CallFunc(GdipSetPixelOffsetMode)(pGraphics, PixelOffsetModeHalf);
+ GpMatrix* pMatrix = NULL;
+ if (pObject2Device) {
+ CallFunc(GdipCreateMatrix2)(pObject2Device->a, pObject2Device->b, pObject2Device->c, pObject2Device->d, pObject2Device->e, pObject2Device->f, &pMatrix);
+ CallFunc(GdipSetWorldTransform)(pGraphics, pMatrix);
+ }
+ PointF *points = FX_Alloc(PointF, nPoints);
+ if (!points) {
+ return FALSE;
+ }
+ BYTE * types = FX_Alloc(BYTE, nPoints);
+ if (!types) {
+ FX_Free(points);
+ return FALSE;
+ }
+ int nSubPathes = 0;
+ FX_BOOL bSubClose = FALSE;
+ int pos_subclose = 0;
+ FX_BOOL bSmooth = FALSE;
+ int startpoint = 0;
+ for(int i = 0; i < nPoints; i++) {
+ points[i].X = pPoints[i].m_PointX;
+ points[i].Y = pPoints[i].m_PointY;
+ FX_FLOAT x, y;
+ if (pObject2Device) {
+ pObject2Device->Transform(pPoints[i].m_PointX, pPoints[i].m_PointY, x, y);
+ } else {
+ x = pPoints[i].m_PointX;
+ y = pPoints[i].m_PointY;
+ }
+ if (x > 50000 * 1.0f) {
+ points[i].X = 50000 * 1.0f;
+ }
+ if (x < -50000 * 1.0f) {
+ points[i].X = -50000 * 1.0f;
+ }
+ if (y > 50000 * 1.0f) {
+ points[i].Y = 50000 * 1.0f;
+ }
+ if (y < -50000 * 1.0f) {
+ points[i].Y = -50000 * 1.0f;
+ }
+ int point_type = pPoints[i].m_Flag & FXPT_TYPE;
+ if(point_type == FXPT_MOVETO) {
+ types[i] = PathPointTypeStart;
+ nSubPathes ++;
+ bSubClose = FALSE;
+ startpoint = i;
+ } else if (point_type == FXPT_LINETO) {
+ types[i] = PathPointTypeLine;
+ if (pPoints[i - 1].m_Flag == FXPT_MOVETO && (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) &&
+ points[i].Y == points[i - 1].Y && points[i].X == points[i - 1].X) {
+ points[i].X += 0.01f;
+ continue;
+ }
+ if (!bSmooth && points[i].X != points[i - 1].X && points[i].Y != points[i - 1].Y) {
+ bSmooth = TRUE;
+ }
+ } else if (point_type == FXPT_BEZIERTO) {
+ types[i] = PathPointTypeBezier;
+ bSmooth = TRUE;
+ }
+ if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) {
+ if (bSubClose) {
+ types[pos_subclose] &= ~PathPointTypeCloseSubpath;
+ } else {
+ bSubClose = TRUE;
+ }
+ pos_subclose = i;
+ types[i] |= PathPointTypeCloseSubpath;
+ if (!bSmooth && points[i].X != points[startpoint].X && points[i].Y != points[startpoint].Y) {
+ bSmooth = TRUE;
+ }
+ }
+ }
+ if (fill_mode & FXFILL_NOPATHSMOOTH) {
+ bSmooth = FALSE;
+ CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeNone);
+ } else if (!(fill_mode & FXFILL_FULLCOVER)) {
+ if (!bSmooth && (fill_mode & 3)) {
+ bSmooth = TRUE;
+ }
+ if (bSmooth || pGraphState && pGraphState->m_LineWidth > 2) {
+ CallFunc(GdipSetSmoothingMode)(pGraphics, SmoothingModeAntiAlias);
+ }
+ }
+ int new_fill_mode = fill_mode & 3;
+ if (nPoints == 4 && pGraphState == NULL) {
+ int v1, v2;
+ if (IsSmallTriangle(points, pObject2Device, v1, v2)) {
+ GpPen* pPen = NULL;
+ CallFunc(GdipCreatePen1)(fill_argb, 1.0f, UnitPixel, &pPen);
+ CallFunc(GdipDrawLineI)(pGraphics, pPen, FXSYS_round(points[v1].X), FXSYS_round(points[v1].Y),
+ FXSYS_round(points[v2].X), FXSYS_round(points[v2].Y));
+ CallFunc(GdipDeletePen)(pPen);
+ return TRUE;
+ }
+ }
+ GpPath* pGpPath = NULL;
+ CallFunc(GdipCreatePath2)(points, types, nPoints, GdiFillType2Gdip(new_fill_mode), &pGpPath);
+ if (!pGpPath) {
+ if (pMatrix) {
+ CallFunc(GdipDeleteMatrix)(pMatrix);
+ }
+ FX_Free(points);
+ FX_Free(types);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ return FALSE;
+ }
+ if (new_fill_mode) {
+ GpBrush* pBrush = _GdipCreateBrush(fill_argb);
+ CallFunc(GdipSetPathFillMode)(pGpPath, GdiFillType2Gdip(new_fill_mode));
+ CallFunc(GdipFillPath)(pGraphics, pBrush, pGpPath);
+ CallFunc(GdipDeleteBrush)(pBrush);
+ }
+ if (pGraphState && stroke_argb) {
+ GpPen* pPen = _GdipCreatePen(pGraphState, pObject2Device, stroke_argb, fill_mode & FX_STROKE_TEXT_MODE);
+ if (nSubPathes == 1) {
+ CallFunc(GdipDrawPath)(pGraphics, pPen, pGpPath);
+ } else {
+ int iStart = 0;
+ for (int i = 0; i < nPoints; i ++) {
+ if (i == nPoints - 1 || types[i + 1] == PathPointTypeStart) {
+ GpPath* pSubPath;
+ CallFunc(GdipCreatePath2)(points + iStart, types + iStart, i - iStart + 1, GdiFillType2Gdip(new_fill_mode), &pSubPath);
+ iStart = i + 1;
+ CallFunc(GdipDrawPath)(pGraphics, pPen, pSubPath);
+ CallFunc(GdipDeletePath)(pSubPath);
+ }
+ }
+ }
+ CallFunc(GdipDeletePen)(pPen);
+ }
+ if (pMatrix) {
+ CallFunc(GdipDeleteMatrix)(pMatrix);
+ }
+ FX_Free(points);
+ FX_Free(types);
+ CallFunc(GdipDeletePath)(pGpPath);
+ CallFunc(GdipDeleteGraphics)(pGraphics);
+ return TRUE;
+}
+class GpStream : public IStream, public CFX_Object
+{
+ LONG m_RefCount;
+ int m_ReadPos;
+ CFX_ByteTextBuf m_InterStream;
+public:
+ GpStream()
+ {
+ m_RefCount = 1;
+ m_ReadPos = 0;
+ }
+ virtual HRESULT STDMETHODCALLTYPE
+ QueryInterface(REFIID iid, void ** ppvObject)
+ {
+ if (iid == __uuidof(IUnknown) || iid == __uuidof(IStream) ||
+ iid == __uuidof(ISequentialStream)) {
+ *ppvObject = static_cast<IStream*>(this);
+ AddRef();
+ return S_OK;
+ } else {
+ return E_NOINTERFACE;
+ }
+ }
+ virtual ULONG STDMETHODCALLTYPE AddRef(void)
+ {
+ return (ULONG)InterlockedIncrement(&m_RefCount);
+ }
+ virtual ULONG STDMETHODCALLTYPE Release(void)
+ {
+ ULONG res = (ULONG) InterlockedDecrement(&m_RefCount);
+ if (res == 0) {
+ delete this;
+ }
+ return res;
+ }
+public:
+ virtual HRESULT STDMETHODCALLTYPE Read(void* Output, ULONG cb, ULONG* pcbRead)
+ {
+ size_t bytes_left;
+ size_t bytes_out;
+ if (pcbRead != NULL) {
+ *pcbRead = 0;
+ }
+ if (m_ReadPos == m_InterStream.GetLength()) {
+ return HRESULT_FROM_WIN32(ERROR_END_OF_MEDIA);
+ }
+ bytes_left = m_InterStream.GetLength() - m_ReadPos;
+ bytes_out = FX_MIN(cb, bytes_left);
+ FXSYS_memcpy32(Output, m_InterStream.GetBuffer() + m_ReadPos, bytes_out);
+ m_ReadPos += (FX_INT32)bytes_out;
+ if (pcbRead != NULL) {
+ *pcbRead = (ULONG)bytes_out;
+ }
+ return S_OK;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Write(void const* Input, ULONG cb, ULONG* pcbWritten)
+ {
+ if (cb <= 0) {
+ if (pcbWritten != NULL) {
+ *pcbWritten = 0;
+ }
+ return S_OK;
+ }
+ m_InterStream.InsertBlock(m_InterStream.GetLength(), Input, cb);
+ if (pcbWritten != NULL) {
+ *pcbWritten = cb;
+ }
+ return S_OK;
+ }
+public:
+ virtual HRESULT STDMETHODCALLTYPE SetSize(ULARGE_INTEGER)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE CopyTo(IStream*, ULARGE_INTEGER, ULARGE_INTEGER*, ULARGE_INTEGER*)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Commit(DWORD)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Revert(void)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE LockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE UnlockRegion(ULARGE_INTEGER, ULARGE_INTEGER, DWORD)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Clone(IStream **)
+ {
+ return E_NOTIMPL;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Seek(LARGE_INTEGER liDistanceToMove, DWORD dwOrigin, ULARGE_INTEGER* lpNewFilePointer)
+ {
+ long start = 0;
+ long new_read_position;
+ switch(dwOrigin) {
+ case STREAM_SEEK_SET:
+ start = 0;
+ break;
+ case STREAM_SEEK_CUR:
+ start = m_ReadPos;
+ break;
+ case STREAM_SEEK_END:
+ start = m_InterStream.GetLength();
+ break;
+ default:
+ return STG_E_INVALIDFUNCTION;
+ break;
+ }
+ new_read_position = start + (long)liDistanceToMove.QuadPart;
+ if (new_read_position < 0 || new_read_position > m_InterStream.GetLength()) {
+ return STG_E_SEEKERROR;
+ }
+ m_ReadPos = new_read_position;
+ if (lpNewFilePointer != NULL) {
+ lpNewFilePointer->QuadPart = m_ReadPos;
+ }
+ return S_OK;
+ }
+ virtual HRESULT STDMETHODCALLTYPE Stat(STATSTG* pStatstg, DWORD grfStatFlag)
+ {
+ if (pStatstg == NULL) {
+ return STG_E_INVALIDFUNCTION;
+ }
+ ZeroMemory(pStatstg, sizeof(STATSTG));
+ pStatstg->cbSize.QuadPart = m_InterStream.GetLength();
+ return S_OK;
+ }
+};
+typedef struct {
+ BITMAPINFO* pbmi;
+ int Stride;
+ LPBYTE pScan0;
+ GpBitmap* pBitmap;
+ BitmapData* pBitmapData;
+ GpStream* pStream;
+} PREVIEW3_DIBITMAP;
+static PREVIEW3_DIBITMAP* LoadDIBitmap(WINDIB_Open_Args_ args)
+{
+ GpBitmap* pBitmap;
+ GpStream* pStream = NULL;
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ Status status = Ok;
+ if (args.flags == WINDIB_OPEN_PATHNAME) {
+ status = CallFunc(GdipCreateBitmapFromFileICM)((wchar_t*)args.path_name, &pBitmap);
+ } else {
+ if (args.memory_size == 0 || !args.memory_base) {
+ return NULL;
+ }
+ pStream = FX_NEW GpStream;
+ if (!pStream) {
+ return NULL;
+ }
+ pStream->Write(args.memory_base, (ULONG)args.memory_size, NULL);
+ status = CallFunc(GdipCreateBitmapFromStreamICM)(pStream, &pBitmap);
+ }
+ if (status != Ok) {
+ if (pStream) {
+ pStream->Release();
+ }
+ return NULL;
+ }
+ UINT height, width;
+ CallFunc(GdipGetImageHeight)(pBitmap, &height);
+ CallFunc(GdipGetImageWidth)(pBitmap, &width);
+ PixelFormat pixel_format;
+ CallFunc(GdipGetImagePixelFormat)(pBitmap, &pixel_format);
+ int info_size = sizeof(BITMAPINFOHEADER);
+ int bpp = 24;
+ int dest_pixel_format = PixelFormat24bppRGB;
+ if (pixel_format == PixelFormat1bppIndexed) {
+ info_size += 8;
+ bpp = 1;
+ dest_pixel_format = PixelFormat1bppIndexed;
+ } else if (pixel_format == PixelFormat8bppIndexed) {
+ info_size += 1024;
+ bpp = 8;
+ dest_pixel_format = PixelFormat8bppIndexed;
+ } else if (pixel_format == PixelFormat32bppARGB) {
+ bpp = 32;
+ dest_pixel_format = PixelFormat32bppARGB;
+ }
+ LPBYTE buf = FX_Alloc(BYTE, info_size);
+ if (!buf) {
+ if (pStream) {
+ pStream->Release();
+ }
+ return NULL;
+ }
+ BITMAPINFOHEADER* pbmih = (BITMAPINFOHEADER*)buf;
+ FXSYS_memset32(buf, 0, info_size);
+ pbmih->biBitCount = bpp;
+ pbmih->biCompression = BI_RGB;
+ pbmih->biHeight = -(int)height;
+ pbmih->biPlanes = 1;
+ pbmih->biWidth = width;
+ Rect rect(0, 0, width, height);
+ BitmapData* pBitmapData = FX_Alloc(BitmapData, 1);
+ if (!pBitmapData) {
+ if (pStream) {
+ pStream->Release();
+ }
+ return NULL;
+ }
+ CallFunc(GdipBitmapLockBits)(pBitmap, &rect, ImageLockModeRead,
+ dest_pixel_format, pBitmapData);
+ if (pixel_format == PixelFormat1bppIndexed || pixel_format == PixelFormat8bppIndexed) {
+ DWORD* ppal = (DWORD*)(buf + sizeof(BITMAPINFOHEADER));
+ struct {
+ UINT flags;
+ UINT Count;
+ DWORD Entries[256];
+ } pal;
+ int size = 0;
+ CallFunc(GdipGetImagePaletteSize)(pBitmap, &size);
+ CallFunc(GdipGetImagePalette)(pBitmap, (ColorPalette*)&pal, size);
+ int entries = pixel_format == PixelFormat1bppIndexed ? 2 : 256;
+ for (int i = 0; i < entries; i ++) {
+ ppal[i] = pal.Entries[i] & 0x00ffffff;
+ }
+ }
+ PREVIEW3_DIBITMAP* pInfo = FX_Alloc(PREVIEW3_DIBITMAP, 1);
+ if (!pInfo) {
+ if (pStream) {
+ pStream->Release();
+ }
+ return NULL;
+ }
+ pInfo->pbmi = (BITMAPINFO*)buf;
+ pInfo->pScan0 = (LPBYTE)pBitmapData->Scan0;
+ pInfo->Stride = pBitmapData->Stride;
+ pInfo->pBitmap = pBitmap;
+ pInfo->pBitmapData = pBitmapData;
+ pInfo->pStream = pStream;
+ return pInfo;
+}
+static void FreeDIBitmap(PREVIEW3_DIBITMAP* pInfo)
+{
+ CGdiplusExt& GdiplusExt = ((CWin32Platform*)CFX_GEModule::Get()->GetPlatformData())->m_GdiplusExt;
+ CallFunc(GdipBitmapUnlockBits)(pInfo->pBitmap, pInfo->pBitmapData);
+ CallFunc(GdipDisposeImage)(pInfo->pBitmap);
+ FX_Free(pInfo->pBitmapData);
+ FX_Free((LPBYTE)pInfo->pbmi);
+ if (pInfo->pStream) {
+ pInfo->pStream->Release();
+ }
+ FX_Free(pInfo);
+}
+CFX_DIBitmap* _FX_WindowsDIB_LoadFromBuf(BITMAPINFO* pbmi, LPVOID pData, FX_BOOL bAlpha);
+CFX_DIBitmap* CGdiplusExt::LoadDIBitmap(WINDIB_Open_Args_ args)
+{
+ PREVIEW3_DIBITMAP* pInfo = ::LoadDIBitmap(args);
+ if (pInfo == NULL) {
+ return NULL;
+ }
+ int height = abs(pInfo->pbmi->bmiHeader.biHeight);
+ int width = pInfo->pbmi->bmiHeader.biWidth;
+ int dest_pitch = (width * pInfo->pbmi->bmiHeader.biBitCount + 31) / 32 * 4;
+ LPBYTE pData = FX_Alloc(BYTE, dest_pitch * height);
+ if (pData == NULL) {
+ FreeDIBitmap(pInfo);
+ return NULL;
+ }
+ if (dest_pitch == pInfo->Stride) {
+ FXSYS_memcpy32(pData, pInfo->pScan0, dest_pitch * height);
+ } else for (int i = 0; i < height; i ++) {
+ FXSYS_memcpy32(pData + dest_pitch * i, pInfo->pScan0 + pInfo->Stride * i, dest_pitch);
+ }
+ CFX_DIBitmap* pDIBitmap = _FX_WindowsDIB_LoadFromBuf(pInfo->pbmi, pData, pInfo->pbmi->bmiHeader.biBitCount == 32);
+ FX_Free(pData);
+ FreeDIBitmap(pInfo);
+ return pDIBitmap;
+}
+#endif
diff --git a/core/src/fxge/win32/fx_win32_print.cpp b/core/src/fxge/win32/fx_win32_print.cpp
index c08c8e7bb6..9e7a0aae95 100644
--- a/core/src/fxge/win32/fx_win32_print.cpp
+++ b/core/src/fxge/win32/fx_win32_print.cpp
@@ -1,426 +1,426 @@
-// 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 "../../../include/fxge/fx_ge.h"
-#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
-#include <windows.h>
-#include "../../../include/fxge/fx_ge_win32.h"
-#include "win32_int.h"
-#include "../../../include/fxge/fx_freetype.h"
-#include "../ge/text_int.h"
-#include "../dib/dib_int.h"
-#define SIZETHRESHOLD 1000
-#define OUTPUTPSLEN 4096
-CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_PRINTER)
-{
- m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE);
- m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE);
- m_bSupportROP = TRUE;
-}
-int CGdiPrinterDriver::GetDeviceCaps(int caps_id)
-{
- if (caps_id == FXDC_HORZ_SIZE) {
- return m_HorzSize;
- }
- if (caps_id == FXDC_VERT_SIZE) {
- return m_VertSize;
- }
- return CGdiDeviceDriver::GetDeviceCaps(caps_id);
-}
-FX_BOOL CGdiPrinterDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform)
-{
- if (pSource->IsAlphaMask()) {
- FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height());
- return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, pSource->GetWidth(), pSource->GetHeight(),
- &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
- }
- ASSERT(pSource != NULL && !pSource->IsAlphaMask() && pSrcRect != NULL);
- ASSERT(blend_type == FXDIB_BLEND_NORMAL);
- if (pSource->HasAlpha()) {
- return FALSE;
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap == NULL) {
- return FALSE;
- }
- return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
-}
-FX_BOOL CGdiPrinterDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (pSource->IsAlphaMask()) {
- int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
- if (pSource->GetBPP() != 1 || alpha != 255 || !m_bSupportROP) {
- return FALSE;
- }
- if (dest_width < 0 || dest_height < 0) {
- CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0);
- if (pFlipped == NULL) {
- return FALSE;
- }
- if (dest_width < 0) {
- dest_left += dest_width;
- }
- if (dest_height < 0) {
- dest_top += dest_height;
- }
- FX_BOOL ret = GDI_StretchBitMask(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), color, flags, alpha_flag, pIccTransform);
- delete pFlipped;
- return ret;
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap == NULL) {
- return FALSE;
- }
- return GDI_StretchBitMask(pBitmap, dest_left, dest_top, dest_width, dest_height, color, flags, alpha_flag, pIccTransform);
- } else {
- ASSERT(pSource != NULL);
- if (pSource->HasAlpha()) {
- return FALSE;
- }
- if (dest_width < 0 || dest_height < 0) {
- CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0);
- if (pFlipped == NULL) {
- return FALSE;
- }
- if (dest_width < 0) {
- dest_left += dest_width;
- }
- if (dest_height < 0) {
- dest_top += dest_height;
- }
- FX_BOOL ret = GDI_StretchDIBits(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), flags, pIccTransform);
- delete pFlipped;
- return ret;
- }
- CFX_DIBExtractor temp(pSource);
- CFX_DIBitmap* pBitmap = temp;
- if (pBitmap == NULL) {
- return FALSE;
- }
- return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform);
- }
-}
-static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix)
-{
- ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || pSrc->GetFormat() == FXDIB_1bppMask || pSrc->GetFormat() == FXDIB_1bppCmyk);
- CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect();
- FX_RECT full_rect = unit_rect.GetOutterRect();
- int full_left = full_rect.left;
- int full_top = full_rect.top;
- CFX_DIBExtractor src_bitmap(pSrc);
- CFX_DIBitmap* pSrcBitmap = src_bitmap;
- if (pSrcBitmap == NULL) {
- return NULL;
- }
- int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight();
- FX_LPBYTE src_buf = pSrcBitmap->GetBuffer();
- FX_DWORD src_pitch = pSrcBitmap->GetPitch();
- FX_FLOAT dest_area = pDestMatrix->GetUnitArea();
- FX_FLOAT area_scale = FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area);
- FX_FLOAT size_scale = FXSYS_sqrt(area_scale);
- CFX_AffineMatrix adjusted_matrix(*pDestMatrix);
- adjusted_matrix.Scale(size_scale, size_scale);
- CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect();
- FX_RECT result_rect = result_rect_f.GetOutterRect();
- CFX_AffineMatrix src2result;
- src2result.e = adjusted_matrix.c + adjusted_matrix.e;
- src2result.f = adjusted_matrix.d + adjusted_matrix.f;
- src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth();
- src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth();
- src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight();
- src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight();
- src2result.TranslateI(-result_rect.left, -result_rect.top);
- CFX_AffineMatrix result2src;
- result2src.SetReverse(src2result);
- CPDF_FixedMatrix result2src_fix(result2src, 8);
- int result_width = result_rect.Width();
- int result_height = result_rect.Height();
- CFX_DIBitmap* pTempBitmap = FX_NEW CFX_DIBitmap;
- if (!pTempBitmap) {
- if (pSrcBitmap != src_bitmap) {
- delete pSrcBitmap;
- }
- return NULL;
- }
- if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) {
- delete pTempBitmap;
- if (pSrcBitmap != src_bitmap) {
- delete pSrcBitmap;
- }
- return NULL;
- }
- pTempBitmap->CopyPalette(pSrc->GetPalette());
- FX_LPBYTE dest_buf = pTempBitmap->GetBuffer();
- int dest_pitch = pTempBitmap->GetPitch();
- FXSYS_memset8(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_height);
- if (pSrcBitmap->IsAlphaMask()) {
- for (int dest_y = 0; dest_y < result_height; dest_y ++) {
- FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch;
- for (int dest_x = 0; dest_x < result_width; dest_x ++) {
- int src_x, src_y;
- result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
- if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
- continue;
- }
- if (!((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8)))) {
- continue;
- }
- dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8);
- }
- }
- } else {
- for (int dest_y = 0; dest_y < result_height; dest_y ++) {
- FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch;
- for (int dest_x = 0; dest_x < result_width; dest_x ++) {
- int src_x, src_y;
- result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
- if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
- continue;
- }
- if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) {
- continue;
- }
- dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8));
- }
- }
- }
- if (pSrcBitmap != src_bitmap) {
- delete pSrcBitmap;
- }
- return pTempBitmap;
-}
-FX_BOOL CGdiPrinterDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (bitmap_alpha < 255 || pSource->HasAlpha() || (pSource->IsAlphaMask() && (pSource->GetBPP() != 1 || !m_bSupportROP))) {
- return FALSE;
- }
- CFX_FloatRect unit_rect = pMatrix->GetUnitRect();
- FX_RECT full_rect = unit_rect.GetOutterRect();
- if (FXSYS_fabs(pMatrix->b) < 0.5f && pMatrix->a != 0 && FXSYS_fabs(pMatrix->c) < 0.5f && pMatrix->d != 0) {
- FX_BOOL bFlipX = pMatrix->a < 0;
- FX_BOOL bFlipY = pMatrix->d > 0;
- return StretchDIBits(pSource, color, bFlipX ? full_rect.right : full_rect.left, bFlipY ? full_rect.bottom : full_rect.top,
- bFlipX ? -full_rect.Width() : full_rect.Width(), bFlipY ? -full_rect.Height() : full_rect.Height(), NULL, 0,
- alpha_flag, pIccTransform, blend_type);
- }
- if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) {
- CFX_DIBitmap* pTransformed = pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0);
- if (pTransformed == NULL) {
- return FALSE;
- }
- FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0,
- alpha_flag, pIccTransform, blend_type);
- delete pTransformed;
- return ret;
- }
- if (pSource->GetBPP() == 1) {
- CFX_DIBitmap* pTransformed = Transform1bppBitmap(pSource, pMatrix);
- if (pIccTransform == NULL) {
- return FALSE;
- }
- SaveState();
- CFX_PathData path;
- path.AppendRect(0, 0, 1.0f, 1.0f);
- SetClip_PathFill(&path, pMatrix, WINDING);
- FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0,
- alpha_flag, pIccTransform, blend_type);
- RestoreState();
- delete pTransformed;
- handle = NULL;
- return ret;
- }
- return FALSE;
-}
-CPSOutput::CPSOutput(HDC hDC)
-{
- m_hDC = hDC;
- m_pBuf = NULL;
-}
-CPSOutput::~CPSOutput()
-{
- if (m_pBuf) {
- FX_Free(m_pBuf);
- }
-}
-void CPSOutput::Init()
-{
- m_pBuf = FX_Alloc(FX_CHAR, 1026);
-}
-void CPSOutput::OutputPS(FX_LPCSTR string, int len)
-{
- if (len < 0) {
- len = (int)FXSYS_strlen(string);
- }
- int sent_len = 0;
- while (len > 0) {
- int send_len = len > 1024 ? 1024 : len;
- *(FX_WORD*)m_pBuf = send_len;
- FXSYS_memcpy(m_pBuf + 2, string + sent_len, send_len);
- int ret = ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, m_pBuf, 0, NULL);
- sent_len += send_len;
- len -= send_len;
- }
-}
-CPSPrinterDriver::CPSPrinterDriver()
-{
- m_pPSOutput = NULL;
- m_bCmykOutput = FALSE;
-}
-CPSPrinterDriver::~CPSPrinterDriver()
-{
- EndRendering();
- if (m_pPSOutput) {
- delete m_pPSOutput;
- }
-}
-FX_BOOL CPSPrinterDriver::Init(HDC hDC, int pslevel, FX_BOOL bCmykOutput)
-{
- m_hDC = hDC;
- m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE);
- m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE);
- m_Width = ::GetDeviceCaps(m_hDC, HORZRES);
- m_Height = ::GetDeviceCaps(m_hDC, VERTRES);
- m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL);
- m_pPSOutput = FX_NEW CPSOutput(hDC);
- if (!m_pPSOutput) {
- return FALSE;
- }
- ((CPSOutput*)m_pPSOutput)->Init();
- m_PSRenderer.Init(m_pPSOutput, pslevel, m_Width, m_Height, bCmykOutput);
- m_bCmykOutput = bCmykOutput;
- HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1);
- int ret = ::GetClipRgn(hDC, hRgn);
- if (ret == 1) {
- ret = ::GetRegionData(hRgn, 0, NULL);
- if (ret) {
- RGNDATA* pData = (RGNDATA*)FX_Alloc(FX_BYTE, ret);
- if (!pData) {
- return FALSE;
- }
- ret = ::GetRegionData(hRgn, ret, pData);
- if (ret) {
- CFX_PathData path;
- path.AllocPointCount(pData->rdh.nCount * 5);
- for (FX_DWORD i = 0; i < pData->rdh.nCount; i ++) {
- RECT* pRect = (RECT*)(pData->Buffer + pData->rdh.nRgnSize * i);
- path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom, (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top);
- }
- m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING);
- }
- FX_Free(pData);
- }
- }
- ::DeleteObject(hRgn);
- return TRUE;
-}
-int CPSPrinterDriver::GetDeviceCaps(int caps_id)
-{
- switch (caps_id) {
- case FXDC_DEVICE_CLASS:
- return FXDC_PRINTER;
- case FXDC_PIXEL_WIDTH:
- return m_Width;
- case FXDC_PIXEL_HEIGHT:
- return m_Height;
- case FXDC_BITS_PIXEL:
- return m_nBitsPerPixel;
- case FXDC_RENDER_CAPS:
- return m_bCmykOutput ? FXRC_BIT_MASK | FXRC_CMYK_OUTPUT : FXRC_BIT_MASK;
- case FXDC_HORZ_SIZE:
- return m_HorzSize;
- case FXDC_VERT_SIZE:
- return m_VertSize;
- }
- return 0;
-}
-FX_BOOL CPSPrinterDriver::StartRendering()
-{
- return m_PSRenderer.StartRendering();
-}
-void CPSPrinterDriver::EndRendering()
-{
- m_PSRenderer.EndRendering();
-}
-void CPSPrinterDriver::SaveState()
-{
- m_PSRenderer.SaveState();
-}
-void CPSPrinterDriver::RestoreState(FX_BOOL bKeepSaved)
-{
- m_PSRenderer.RestoreState(bKeepSaved);
-}
-FX_BOOL CPSPrinterDriver::SetClip_PathFill(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device,
- int fill_mode)
-{
- m_PSRenderer.SetClip_PathFill(pPathData, pObject2Device, fill_mode);
- return TRUE;
-}
-FX_BOOL CPSPrinterDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState)
-{
- m_PSRenderer.SetClip_PathStroke(pPathData, pObject2Device, pGraphState);
- return TRUE;
-}
-FX_BOOL CPSPrinterDriver::DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState, FX_ARGB fill_color, FX_ARGB stroke_color,
- int fill_mode, int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState, fill_color, stroke_color, fill_mode & 3, alpha_flag, pIccTransform);
-}
-FX_BOOL CPSPrinterDriver::GetClipBox(FX_RECT* pRect)
-{
- *pRect = m_PSRenderer.GetClipBox();
- return TRUE;
-}
-FX_BOOL CPSPrinterDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- return m_PSRenderer.SetDIBits(pBitmap, color, left, top, alpha_flag, pIccTransform);
-}
-FX_BOOL CPSPrinterDriver::StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- return m_PSRenderer.StretchDIBits(pBitmap, color, dest_left, dest_top, dest_width, dest_height, flags, alpha_flag, pIccTransform);
-}
-FX_BOOL CPSPrinterDriver::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type)
-{
- if (blend_type != FXDIB_BLEND_NORMAL) {
- return FALSE;
- }
- if (bitmap_alpha < 255) {
- return FALSE;
- }
- handle = NULL;
- return m_PSRenderer.DrawDIBits(pBitmap, color, pMatrix, render_flags, alpha_flag, pIccTransform);
-}
-FX_BOOL CPSPrinterDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
- CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
- int alpha_flag, void* pIccTransform)
-{
- return m_PSRenderer.DrawText(nChars, pCharPos, pFont, pCache, pObject2Device, font_size, color, alpha_flag, pIccTransform);
-}
-#endif
+// 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 "../../../include/fxge/fx_ge.h"
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_
+#include <windows.h>
+#include "../../../include/fxge/fx_ge_win32.h"
+#include "win32_int.h"
+#include "../../../include/fxge/fx_freetype.h"
+#include "../ge/text_int.h"
+#include "../dib/dib_int.h"
+#define SIZETHRESHOLD 1000
+#define OUTPUTPSLEN 4096
+CGdiPrinterDriver::CGdiPrinterDriver(HDC hDC) : CGdiDeviceDriver(hDC, FXDC_PRINTER)
+{
+ m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE);
+ m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE);
+ m_bSupportROP = TRUE;
+}
+int CGdiPrinterDriver::GetDeviceCaps(int caps_id)
+{
+ if (caps_id == FXDC_HORZ_SIZE) {
+ return m_HorzSize;
+ }
+ if (caps_id == FXDC_VERT_SIZE) {
+ return m_VertSize;
+ }
+ return CGdiDeviceDriver::GetDeviceCaps(caps_id);
+}
+FX_BOOL CGdiPrinterDriver::SetDIBits(const CFX_DIBSource* pSource, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform)
+{
+ if (pSource->IsAlphaMask()) {
+ FX_RECT clip_rect(left, top, left + pSrcRect->Width(), top + pSrcRect->Height());
+ return StretchDIBits(pSource, color, left - pSrcRect->left, top - pSrcRect->top, pSource->GetWidth(), pSource->GetHeight(),
+ &clip_rect, 0, alpha_flag, pIccTransform, FXDIB_BLEND_NORMAL);
+ }
+ ASSERT(pSource != NULL && !pSource->IsAlphaMask() && pSrcRect != NULL);
+ ASSERT(blend_type == FXDIB_BLEND_NORMAL);
+ if (pSource->HasAlpha()) {
+ return FALSE;
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ return GDI_SetDIBits(pBitmap, pSrcRect, left, top, pIccTransform);
+}
+FX_BOOL CGdiPrinterDriver::StretchDIBits(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (pSource->IsAlphaMask()) {
+ int alpha = FXGETFLAG_COLORTYPE(alpha_flag) ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
+ if (pSource->GetBPP() != 1 || alpha != 255 || !m_bSupportROP) {
+ return FALSE;
+ }
+ if (dest_width < 0 || dest_height < 0) {
+ CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0);
+ if (pFlipped == NULL) {
+ return FALSE;
+ }
+ if (dest_width < 0) {
+ dest_left += dest_width;
+ }
+ if (dest_height < 0) {
+ dest_top += dest_height;
+ }
+ FX_BOOL ret = GDI_StretchBitMask(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), color, flags, alpha_flag, pIccTransform);
+ delete pFlipped;
+ return ret;
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ return GDI_StretchBitMask(pBitmap, dest_left, dest_top, dest_width, dest_height, color, flags, alpha_flag, pIccTransform);
+ } else {
+ ASSERT(pSource != NULL);
+ if (pSource->HasAlpha()) {
+ return FALSE;
+ }
+ if (dest_width < 0 || dest_height < 0) {
+ CFX_DIBitmap* pFlipped = pSource->FlipImage(dest_width < 0, dest_height < 0);
+ if (pFlipped == NULL) {
+ return FALSE;
+ }
+ if (dest_width < 0) {
+ dest_left += dest_width;
+ }
+ if (dest_height < 0) {
+ dest_top += dest_height;
+ }
+ FX_BOOL ret = GDI_StretchDIBits(pFlipped, dest_left, dest_top, abs(dest_width), abs(dest_height), flags, pIccTransform);
+ delete pFlipped;
+ return ret;
+ }
+ CFX_DIBExtractor temp(pSource);
+ CFX_DIBitmap* pBitmap = temp;
+ if (pBitmap == NULL) {
+ return FALSE;
+ }
+ return GDI_StretchDIBits(pBitmap, dest_left, dest_top, dest_width, dest_height, flags, pIccTransform);
+ }
+}
+static CFX_DIBitmap* Transform1bppBitmap(const CFX_DIBSource* pSrc, const CFX_AffineMatrix* pDestMatrix)
+{
+ ASSERT(pSrc->GetFormat() == FXDIB_1bppRgb || pSrc->GetFormat() == FXDIB_1bppMask || pSrc->GetFormat() == FXDIB_1bppCmyk);
+ CFX_FloatRect unit_rect = pDestMatrix->GetUnitRect();
+ FX_RECT full_rect = unit_rect.GetOutterRect();
+ int full_left = full_rect.left;
+ int full_top = full_rect.top;
+ CFX_DIBExtractor src_bitmap(pSrc);
+ CFX_DIBitmap* pSrcBitmap = src_bitmap;
+ if (pSrcBitmap == NULL) {
+ return NULL;
+ }
+ int src_width = pSrcBitmap->GetWidth(), src_height = pSrcBitmap->GetHeight();
+ FX_LPBYTE src_buf = pSrcBitmap->GetBuffer();
+ FX_DWORD src_pitch = pSrcBitmap->GetPitch();
+ FX_FLOAT dest_area = pDestMatrix->GetUnitArea();
+ FX_FLOAT area_scale = FXSYS_Div((FX_FLOAT)(src_width * src_height), dest_area);
+ FX_FLOAT size_scale = FXSYS_sqrt(area_scale);
+ CFX_AffineMatrix adjusted_matrix(*pDestMatrix);
+ adjusted_matrix.Scale(size_scale, size_scale);
+ CFX_FloatRect result_rect_f = adjusted_matrix.GetUnitRect();
+ FX_RECT result_rect = result_rect_f.GetOutterRect();
+ CFX_AffineMatrix src2result;
+ src2result.e = adjusted_matrix.c + adjusted_matrix.e;
+ src2result.f = adjusted_matrix.d + adjusted_matrix.f;
+ src2result.a = adjusted_matrix.a / pSrcBitmap->GetWidth();
+ src2result.b = adjusted_matrix.b / pSrcBitmap->GetWidth();
+ src2result.c = -adjusted_matrix.c / pSrcBitmap->GetHeight();
+ src2result.d = -adjusted_matrix.d / pSrcBitmap->GetHeight();
+ src2result.TranslateI(-result_rect.left, -result_rect.top);
+ CFX_AffineMatrix result2src;
+ result2src.SetReverse(src2result);
+ CPDF_FixedMatrix result2src_fix(result2src, 8);
+ int result_width = result_rect.Width();
+ int result_height = result_rect.Height();
+ CFX_DIBitmap* pTempBitmap = FX_NEW CFX_DIBitmap;
+ if (!pTempBitmap) {
+ if (pSrcBitmap != src_bitmap) {
+ delete pSrcBitmap;
+ }
+ return NULL;
+ }
+ if (!pTempBitmap->Create(result_width, result_height, pSrc->GetFormat())) {
+ delete pTempBitmap;
+ if (pSrcBitmap != src_bitmap) {
+ delete pSrcBitmap;
+ }
+ return NULL;
+ }
+ pTempBitmap->CopyPalette(pSrc->GetPalette());
+ FX_LPBYTE dest_buf = pTempBitmap->GetBuffer();
+ int dest_pitch = pTempBitmap->GetPitch();
+ FXSYS_memset8(dest_buf, pSrc->IsAlphaMask() ? 0 : 0xff, dest_pitch * result_height);
+ if (pSrcBitmap->IsAlphaMask()) {
+ for (int dest_y = 0; dest_y < result_height; dest_y ++) {
+ FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch;
+ for (int dest_x = 0; dest_x < result_width; dest_x ++) {
+ int src_x, src_y;
+ result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
+ if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
+ continue;
+ }
+ if (!((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8)))) {
+ continue;
+ }
+ dest_scan[dest_x / 8] |= 1 << (7 - dest_x % 8);
+ }
+ }
+ } else {
+ for (int dest_y = 0; dest_y < result_height; dest_y ++) {
+ FX_LPBYTE dest_scan = dest_buf + dest_y * dest_pitch;
+ for (int dest_x = 0; dest_x < result_width; dest_x ++) {
+ int src_x, src_y;
+ result2src_fix.Transform(dest_x, dest_y, src_x, src_y);
+ if (src_x < 0 || src_x >= src_width || src_y < 0 || src_y >= src_height) {
+ continue;
+ }
+ if ((src_buf + src_pitch * src_y)[src_x / 8] & (1 << (7 - src_x % 8))) {
+ continue;
+ }
+ dest_scan[dest_x / 8] &= ~(1 << (7 - dest_x % 8));
+ }
+ }
+ }
+ if (pSrcBitmap != src_bitmap) {
+ delete pSrcBitmap;
+ }
+ return pTempBitmap;
+}
+FX_BOOL CGdiPrinterDriver::StartDIBits(const CFX_DIBSource* pSource, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (bitmap_alpha < 255 || pSource->HasAlpha() || (pSource->IsAlphaMask() && (pSource->GetBPP() != 1 || !m_bSupportROP))) {
+ return FALSE;
+ }
+ CFX_FloatRect unit_rect = pMatrix->GetUnitRect();
+ FX_RECT full_rect = unit_rect.GetOutterRect();
+ if (FXSYS_fabs(pMatrix->b) < 0.5f && pMatrix->a != 0 && FXSYS_fabs(pMatrix->c) < 0.5f && pMatrix->d != 0) {
+ FX_BOOL bFlipX = pMatrix->a < 0;
+ FX_BOOL bFlipY = pMatrix->d > 0;
+ return StretchDIBits(pSource, color, bFlipX ? full_rect.right : full_rect.left, bFlipY ? full_rect.bottom : full_rect.top,
+ bFlipX ? -full_rect.Width() : full_rect.Width(), bFlipY ? -full_rect.Height() : full_rect.Height(), NULL, 0,
+ alpha_flag, pIccTransform, blend_type);
+ }
+ if (FXSYS_fabs(pMatrix->a) < 0.5f && FXSYS_fabs(pMatrix->d) < 0.5f) {
+ CFX_DIBitmap* pTransformed = pSource->SwapXY(pMatrix->c > 0, pMatrix->b < 0);
+ if (pTransformed == NULL) {
+ return FALSE;
+ }
+ FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0,
+ alpha_flag, pIccTransform, blend_type);
+ delete pTransformed;
+ return ret;
+ }
+ if (pSource->GetBPP() == 1) {
+ CFX_DIBitmap* pTransformed = Transform1bppBitmap(pSource, pMatrix);
+ if (pIccTransform == NULL) {
+ return FALSE;
+ }
+ SaveState();
+ CFX_PathData path;
+ path.AppendRect(0, 0, 1.0f, 1.0f);
+ SetClip_PathFill(&path, pMatrix, WINDING);
+ FX_BOOL ret = StretchDIBits(pTransformed, color, full_rect.left, full_rect.top, full_rect.Width(), full_rect.Height(), NULL, 0,
+ alpha_flag, pIccTransform, blend_type);
+ RestoreState();
+ delete pTransformed;
+ handle = NULL;
+ return ret;
+ }
+ return FALSE;
+}
+CPSOutput::CPSOutput(HDC hDC)
+{
+ m_hDC = hDC;
+ m_pBuf = NULL;
+}
+CPSOutput::~CPSOutput()
+{
+ if (m_pBuf) {
+ FX_Free(m_pBuf);
+ }
+}
+void CPSOutput::Init()
+{
+ m_pBuf = FX_Alloc(FX_CHAR, 1026);
+}
+void CPSOutput::OutputPS(FX_LPCSTR string, int len)
+{
+ if (len < 0) {
+ len = (int)FXSYS_strlen(string);
+ }
+ int sent_len = 0;
+ while (len > 0) {
+ int send_len = len > 1024 ? 1024 : len;
+ *(FX_WORD*)m_pBuf = send_len;
+ FXSYS_memcpy(m_pBuf + 2, string + sent_len, send_len);
+ int ret = ExtEscape(m_hDC, PASSTHROUGH, send_len + 2, m_pBuf, 0, NULL);
+ sent_len += send_len;
+ len -= send_len;
+ }
+}
+CPSPrinterDriver::CPSPrinterDriver()
+{
+ m_pPSOutput = NULL;
+ m_bCmykOutput = FALSE;
+}
+CPSPrinterDriver::~CPSPrinterDriver()
+{
+ EndRendering();
+ if (m_pPSOutput) {
+ delete m_pPSOutput;
+ }
+}
+FX_BOOL CPSPrinterDriver::Init(HDC hDC, int pslevel, FX_BOOL bCmykOutput)
+{
+ m_hDC = hDC;
+ m_HorzSize = ::GetDeviceCaps(m_hDC, HORZSIZE);
+ m_VertSize = ::GetDeviceCaps(m_hDC, VERTSIZE);
+ m_Width = ::GetDeviceCaps(m_hDC, HORZRES);
+ m_Height = ::GetDeviceCaps(m_hDC, VERTRES);
+ m_nBitsPerPixel = ::GetDeviceCaps(m_hDC, BITSPIXEL);
+ m_pPSOutput = FX_NEW CPSOutput(hDC);
+ if (!m_pPSOutput) {
+ return FALSE;
+ }
+ ((CPSOutput*)m_pPSOutput)->Init();
+ m_PSRenderer.Init(m_pPSOutput, pslevel, m_Width, m_Height, bCmykOutput);
+ m_bCmykOutput = bCmykOutput;
+ HRGN hRgn = ::CreateRectRgn(0, 0, 1, 1);
+ int ret = ::GetClipRgn(hDC, hRgn);
+ if (ret == 1) {
+ ret = ::GetRegionData(hRgn, 0, NULL);
+ if (ret) {
+ RGNDATA* pData = (RGNDATA*)FX_Alloc(FX_BYTE, ret);
+ if (!pData) {
+ return FALSE;
+ }
+ ret = ::GetRegionData(hRgn, ret, pData);
+ if (ret) {
+ CFX_PathData path;
+ path.AllocPointCount(pData->rdh.nCount * 5);
+ for (FX_DWORD i = 0; i < pData->rdh.nCount; i ++) {
+ RECT* pRect = (RECT*)(pData->Buffer + pData->rdh.nRgnSize * i);
+ path.AppendRect((FX_FLOAT)pRect->left, (FX_FLOAT)pRect->bottom, (FX_FLOAT)pRect->right, (FX_FLOAT)pRect->top);
+ }
+ m_PSRenderer.SetClip_PathFill(&path, NULL, FXFILL_WINDING);
+ }
+ FX_Free(pData);
+ }
+ }
+ ::DeleteObject(hRgn);
+ return TRUE;
+}
+int CPSPrinterDriver::GetDeviceCaps(int caps_id)
+{
+ switch (caps_id) {
+ case FXDC_DEVICE_CLASS:
+ return FXDC_PRINTER;
+ case FXDC_PIXEL_WIDTH:
+ return m_Width;
+ case FXDC_PIXEL_HEIGHT:
+ return m_Height;
+ case FXDC_BITS_PIXEL:
+ return m_nBitsPerPixel;
+ case FXDC_RENDER_CAPS:
+ return m_bCmykOutput ? FXRC_BIT_MASK | FXRC_CMYK_OUTPUT : FXRC_BIT_MASK;
+ case FXDC_HORZ_SIZE:
+ return m_HorzSize;
+ case FXDC_VERT_SIZE:
+ return m_VertSize;
+ }
+ return 0;
+}
+FX_BOOL CPSPrinterDriver::StartRendering()
+{
+ return m_PSRenderer.StartRendering();
+}
+void CPSPrinterDriver::EndRendering()
+{
+ m_PSRenderer.EndRendering();
+}
+void CPSPrinterDriver::SaveState()
+{
+ m_PSRenderer.SaveState();
+}
+void CPSPrinterDriver::RestoreState(FX_BOOL bKeepSaved)
+{
+ m_PSRenderer.RestoreState(bKeepSaved);
+}
+FX_BOOL CPSPrinterDriver::SetClip_PathFill(const CFX_PathData* pPathData, const CFX_AffineMatrix* pObject2Device,
+ int fill_mode)
+{
+ m_PSRenderer.SetClip_PathFill(pPathData, pObject2Device, fill_mode);
+ return TRUE;
+}
+FX_BOOL CPSPrinterDriver::SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState)
+{
+ m_PSRenderer.SetClip_PathStroke(pPathData, pObject2Device, pGraphState);
+ return TRUE;
+}
+FX_BOOL CPSPrinterDriver::DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState, FX_ARGB fill_color, FX_ARGB stroke_color,
+ int fill_mode, int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ return m_PSRenderer.DrawPath(pPathData, pObject2Device, pGraphState, fill_color, stroke_color, fill_mode & 3, alpha_flag, pIccTransform);
+}
+FX_BOOL CPSPrinterDriver::GetClipBox(FX_RECT* pRect)
+{
+ *pRect = m_PSRenderer.GetClipBox();
+ return TRUE;
+}
+FX_BOOL CPSPrinterDriver::SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ return m_PSRenderer.SetDIBits(pBitmap, color, left, top, alpha_flag, pIccTransform);
+}
+FX_BOOL CPSPrinterDriver::StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ return m_PSRenderer.StretchDIBits(pBitmap, color, dest_left, dest_top, dest_width, dest_height, flags, alpha_flag, pIccTransform);
+}
+FX_BOOL CPSPrinterDriver::StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type)
+{
+ if (blend_type != FXDIB_BLEND_NORMAL) {
+ return FALSE;
+ }
+ if (bitmap_alpha < 255) {
+ return FALSE;
+ }
+ handle = NULL;
+ return m_PSRenderer.DrawDIBits(pBitmap, color, pMatrix, render_flags, alpha_flag, pIccTransform);
+}
+FX_BOOL CPSPrinterDriver::DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
+ CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
+ int alpha_flag, void* pIccTransform)
+{
+ return m_PSRenderer.DrawText(nChars, pCharPos, pFont, pCache, pObject2Device, font_size, color, alpha_flag, pIccTransform);
+}
+#endif
diff --git a/core/src/fxge/win32/win32_int.h b/core/src/fxge/win32/win32_int.h
index 3f940eda1e..83595cbf8d 100644
--- a/core/src/fxge/win32/win32_int.h
+++ b/core/src/fxge/win32/win32_int.h
@@ -1,238 +1,238 @@
-// 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
-
-struct WINDIB_Open_Args_;
-class CGdiplusExt
-{
-public:
- CGdiplusExt();
- ~CGdiplusExt();
- void Load();
- FX_BOOL IsAvailable()
- {
- return m_hModule != NULL;
- }
- FX_BOOL StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags);
- FX_BOOL StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, int flags);
- FX_BOOL DrawPath(HDC hDC, const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_argb,
- FX_DWORD stroke_argb,
- int fill_mode
- );
-
- void* LoadMemFont(FX_BYTE* pData, FX_DWORD size);
- void DeleteMemFont(void* pFontCollection);
- FX_BOOL GdipCreateFromImage(void* bitmap, void** graphics);
- void GdipDeleteGraphics(void* graphics);
- void GdipSetTextRenderingHint(void* graphics, int mode);
- void GdipSetPageUnit(void* graphics, FX_DWORD unit);
- void GdipSetWorldTransform(void* graphics, void* pMatrix);
- FX_BOOL GdipDrawDriverString(void *graphics, unsigned short *text, int length, void *font, void* brush, void *positions, int flags, const void *matrix);
- void GdipCreateBrush(FX_DWORD fill_argb, void** pBrush);
- void GdipDeleteBrush(void* pBrush);
- void GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix);
- void GdipDeleteMatrix(void* matrix);
- FX_BOOL GdipCreateFontFamilyFromName(FX_LPCWSTR name, void* pFontCollection, void**pFamily);
- void GdipDeleteFontFamily(void* pFamily);
- FX_BOOL GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont);
- void* GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle);
- void GdipDeleteFont(void* pFont);
- FX_BOOL GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap);
- void GdipDisposeImage(void* bitmap);
- void GdipGetFontSize(void *pFont, FX_FLOAT *size);
- void* GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face);
- FX_BOOL GdiRemoveFontMemResourceEx(void* handle);
- void* m_Functions[100];
- void* m_pGdiAddFontMemResourceEx;
- void* m_pGdiRemoveFontMemResourseEx;
- CFX_DIBitmap* LoadDIBitmap(WINDIB_Open_Args_ args);
-protected:
- HMODULE m_hModule;
- HMODULE m_GdiModule;
-};
-#include "dwrite_int.h"
-class CWin32Platform : public CFX_Object
-{
-public:
- FX_BOOL m_bHalfTone;
- CGdiplusExt m_GdiplusExt;
- CDWriteExt m_DWriteExt;
-};
-class CGdiDeviceDriver : public IFX_RenderDeviceDriver
-{
-protected:
- virtual int GetDeviceCaps(int caps_id);
- virtual void SaveState()
- {
- SaveDC(m_hDC);
- }
- virtual void RestoreState(FX_BOOL bKeepSaved = FALSE)
- {
- RestoreDC(m_hDC, -1);
- if (bKeepSaved) {
- SaveDC(m_hDC);
- }
- }
- virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- int fill_mode
- );
- virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState
- );
- virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color,
- FX_DWORD stroke_color,
- int fill_mode,
- int alpha_flag,
- void* pIccTransform,
- int blend_type
- );
- virtual FX_BOOL FillRect(const FX_RECT* pRect,
- FX_DWORD fill_color,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_LPVOID GetClipRgn() ;
- virtual FX_BOOL SetClipRgn(FX_LPVOID pRgn) ;
- virtual FX_BOOL GetClipBox(FX_RECT* pRect);
- virtual FX_BOOL DeleteDeviceRgn(FX_LPVOID pRgn);
- virtual void DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);
- virtual void* GetPlatformSurface()
- {
- return (void*)m_hDC;
- }
- FX_BOOL GDI_SetDIBits(const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect, int left, int top,
- void* pIccTransform);
- FX_BOOL GDI_StretchDIBits(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD flags,
- void* pIccTransform);
- FX_BOOL GDI_StretchBitMask(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
- int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
- int alpha_flag, void* pIccTransform);
- HDC m_hDC;
- int m_Width, m_Height, m_nBitsPerPixel;
- int m_DeviceClass, m_RenderCaps;
- CGdiDeviceDriver(HDC hDC, int device_class);
- ~CGdiDeviceDriver() {}
-};
-class CGdiDisplayDriver : public CGdiDeviceDriver
-{
-public:
- CGdiDisplayDriver(HDC hDC);
-protected:
- virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE);
- virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform);
- virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type)
- {
- return FALSE;
- }
- FX_BOOL UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags,
- int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
-};
-class CGdiPrinterDriver : public CGdiDeviceDriver
-{
-public:
- CGdiPrinterDriver(HDC hDC);
-protected:
- virtual int GetDeviceCaps(int caps_id);
- virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform);
- virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type);
- int m_HorzSize, m_VertSize;
- FX_BOOL m_bSupportROP;
-};
-class CPSOutput : public IFX_PSOutput, public CFX_Object
-{
-public:
- CPSOutput(HDC hDC);
- virtual ~CPSOutput();
- virtual void Release()
- {
- delete this;
- }
- void Init();
- virtual void OutputPS(FX_LPCSTR string, int len);
- HDC m_hDC;
- FX_LPSTR m_pBuf;
-};
-class CPSPrinterDriver : public IFX_RenderDeviceDriver
-{
-public:
- CPSPrinterDriver();
- FX_BOOL Init(HDC hDC, int ps_level, FX_BOOL bCmykOutput);
- ~CPSPrinterDriver();
-protected:
- virtual FX_BOOL IsPSPrintDriver()
- {
- return TRUE;
- }
- virtual int GetDeviceCaps(int caps_id);
- virtual FX_BOOL StartRendering();
- virtual void EndRendering();
- virtual void SaveState();
- virtual void RestoreState(FX_BOOL bKeepSaved = FALSE);
- virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- int fill_mode
- );
- virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState
- );
- virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
- const CFX_AffineMatrix* pObject2Device,
- const CFX_GraphStateData* pGraphState,
- FX_DWORD fill_color,
- FX_DWORD stroke_color,
- int fill_mode,
- int alpha_flag,
- void* pIccTransform,
- int blend_type
- );
- virtual FX_BOOL GetClipBox(FX_RECT* pRect);
- virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
- int alpha_flag, void* pIccTransform);
- virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
- int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
- const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
- int alpha_flag, void* pIccTransform, int blend_type);
- virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
- CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
- int alpha_flag, void* pIccTransform);
- virtual void* GetPlatformSurface()
- {
- return (void*)m_hDC;
- }
- HDC m_hDC;
- FX_BOOL m_bCmykOutput;
- int m_Width, m_Height, m_nBitsPerPixel;
- int m_HorzSize, m_VertSize;
- CPSOutput* m_pPSOutput;
- CFX_PSRenderer m_PSRenderer;
-};
-void _Color2Argb(FX_ARGB& argb, FX_DWORD color, int alpha_flag, void* pIccTransform);
+// 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
+
+struct WINDIB_Open_Args_;
+class CGdiplusExt
+{
+public:
+ CGdiplusExt();
+ ~CGdiplusExt();
+ void Load();
+ FX_BOOL IsAvailable()
+ {
+ return m_hModule != NULL;
+ }
+ FX_BOOL StretchBitMask(HDC hDC, BOOL bMonoDevice, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD argb, const FX_RECT* pClipRect, int flags);
+ FX_BOOL StretchDIBits(HDC hDC, const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, int flags);
+ FX_BOOL DrawPath(HDC hDC, const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_argb,
+ FX_DWORD stroke_argb,
+ int fill_mode
+ );
+
+ void* LoadMemFont(FX_BYTE* pData, FX_DWORD size);
+ void DeleteMemFont(void* pFontCollection);
+ FX_BOOL GdipCreateFromImage(void* bitmap, void** graphics);
+ void GdipDeleteGraphics(void* graphics);
+ void GdipSetTextRenderingHint(void* graphics, int mode);
+ void GdipSetPageUnit(void* graphics, FX_DWORD unit);
+ void GdipSetWorldTransform(void* graphics, void* pMatrix);
+ FX_BOOL GdipDrawDriverString(void *graphics, unsigned short *text, int length, void *font, void* brush, void *positions, int flags, const void *matrix);
+ void GdipCreateBrush(FX_DWORD fill_argb, void** pBrush);
+ void GdipDeleteBrush(void* pBrush);
+ void GdipCreateMatrix(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, void** matrix);
+ void GdipDeleteMatrix(void* matrix);
+ FX_BOOL GdipCreateFontFamilyFromName(FX_LPCWSTR name, void* pFontCollection, void**pFamily);
+ void GdipDeleteFontFamily(void* pFamily);
+ FX_BOOL GdipCreateFontFromFamily(void* pFamily, FX_FLOAT font_size, int fontstyle, int flag, void** pFont);
+ void* GdipCreateFontFromCollection(void* pFontCollection, FX_FLOAT font_size, int fontstyle);
+ void GdipDeleteFont(void* pFont);
+ FX_BOOL GdipCreateBitmap(CFX_DIBitmap* pBitmap, void**bitmap);
+ void GdipDisposeImage(void* bitmap);
+ void GdipGetFontSize(void *pFont, FX_FLOAT *size);
+ void* GdiAddFontMemResourceEx(void *pFontdata, FX_DWORD size, void* pdv, FX_DWORD* num_face);
+ FX_BOOL GdiRemoveFontMemResourceEx(void* handle);
+ void* m_Functions[100];
+ void* m_pGdiAddFontMemResourceEx;
+ void* m_pGdiRemoveFontMemResourseEx;
+ CFX_DIBitmap* LoadDIBitmap(WINDIB_Open_Args_ args);
+protected:
+ HMODULE m_hModule;
+ HMODULE m_GdiModule;
+};
+#include "dwrite_int.h"
+class CWin32Platform : public CFX_Object
+{
+public:
+ FX_BOOL m_bHalfTone;
+ CGdiplusExt m_GdiplusExt;
+ CDWriteExt m_DWriteExt;
+};
+class CGdiDeviceDriver : public IFX_RenderDeviceDriver
+{
+protected:
+ virtual int GetDeviceCaps(int caps_id);
+ virtual void SaveState()
+ {
+ SaveDC(m_hDC);
+ }
+ virtual void RestoreState(FX_BOOL bKeepSaved = FALSE)
+ {
+ RestoreDC(m_hDC, -1);
+ if (bKeepSaved) {
+ SaveDC(m_hDC);
+ }
+ }
+ virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ int fill_mode
+ );
+ virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState
+ );
+ virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type
+ );
+ virtual FX_BOOL FillRect(const FX_RECT* pRect,
+ FX_DWORD fill_color,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL DrawCosmeticLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_DWORD color,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_LPVOID GetClipRgn() ;
+ virtual FX_BOOL SetClipRgn(FX_LPVOID pRgn) ;
+ virtual FX_BOOL GetClipBox(FX_RECT* pRect);
+ virtual FX_BOOL DeleteDeviceRgn(FX_LPVOID pRgn);
+ virtual void DrawLine(FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2);
+ virtual void* GetPlatformSurface()
+ {
+ return (void*)m_hDC;
+ }
+ FX_BOOL GDI_SetDIBits(const CFX_DIBitmap* pBitmap, const FX_RECT* pSrcRect, int left, int top,
+ void* pIccTransform);
+ FX_BOOL GDI_StretchDIBits(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD flags,
+ void* pIccTransform);
+ FX_BOOL GDI_StretchBitMask(const CFX_DIBitmap* pBitmap, int dest_left, int dest_top,
+ int dest_width, int dest_height, FX_DWORD bitmap_color, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform);
+ HDC m_hDC;
+ int m_Width, m_Height, m_nBitsPerPixel;
+ int m_DeviceClass, m_RenderCaps;
+ CGdiDeviceDriver(HDC hDC, int device_class);
+ ~CGdiDeviceDriver() {}
+};
+class CGdiDisplayDriver : public CGdiDeviceDriver
+{
+public:
+ CGdiDisplayDriver(HDC hDC);
+protected:
+ virtual FX_BOOL GetDIBits(CFX_DIBitmap* pBitmap, int left, int top, void* pIccTransform = NULL, FX_BOOL bDEdge = FALSE);
+ virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform);
+ virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type)
+ {
+ return FALSE;
+ }
+ FX_BOOL UseFoxitStretchEngine(const CFX_DIBSource* pSource, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, int render_flags,
+ int alpha_flag = 0, void* pIccTransform = NULL, int blend_type = FXDIB_BLEND_NORMAL);
+};
+class CGdiPrinterDriver : public CGdiDeviceDriver
+{
+public:
+ CGdiPrinterDriver(HDC hDC);
+protected:
+ virtual int GetDeviceCaps(int caps_id);
+ virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform);
+ virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ int m_HorzSize, m_VertSize;
+ FX_BOOL m_bSupportROP;
+};
+class CPSOutput : public IFX_PSOutput, public CFX_Object
+{
+public:
+ CPSOutput(HDC hDC);
+ virtual ~CPSOutput();
+ virtual void Release()
+ {
+ delete this;
+ }
+ void Init();
+ virtual void OutputPS(FX_LPCSTR string, int len);
+ HDC m_hDC;
+ FX_LPSTR m_pBuf;
+};
+class CPSPrinterDriver : public IFX_RenderDeviceDriver
+{
+public:
+ CPSPrinterDriver();
+ FX_BOOL Init(HDC hDC, int ps_level, FX_BOOL bCmykOutput);
+ ~CPSPrinterDriver();
+protected:
+ virtual FX_BOOL IsPSPrintDriver()
+ {
+ return TRUE;
+ }
+ virtual int GetDeviceCaps(int caps_id);
+ virtual FX_BOOL StartRendering();
+ virtual void EndRendering();
+ virtual void SaveState();
+ virtual void RestoreState(FX_BOOL bKeepSaved = FALSE);
+ virtual FX_BOOL SetClip_PathFill(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ int fill_mode
+ );
+ virtual FX_BOOL SetClip_PathStroke(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState
+ );
+ virtual FX_BOOL DrawPath(const CFX_PathData* pPathData,
+ const CFX_AffineMatrix* pObject2Device,
+ const CFX_GraphStateData* pGraphState,
+ FX_DWORD fill_color,
+ FX_DWORD stroke_color,
+ int fill_mode,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type
+ );
+ virtual FX_BOOL GetClipBox(FX_RECT* pRect);
+ virtual FX_BOOL SetDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, const FX_RECT* pSrcRect, int left, int top, int blend_type,
+ int alpha_flag, void* pIccTransform);
+ virtual FX_BOOL StretchDIBits(const CFX_DIBSource* pBitmap, FX_DWORD color, int dest_left, int dest_top,
+ int dest_width, int dest_height, const FX_RECT* pClipRect, FX_DWORD flags,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL StartDIBits(const CFX_DIBSource* pBitmap, int bitmap_alpha, FX_DWORD color,
+ const CFX_AffineMatrix* pMatrix, FX_DWORD render_flags, FX_LPVOID& handle,
+ int alpha_flag, void* pIccTransform, int blend_type);
+ virtual FX_BOOL DrawDeviceText(int nChars, const FXTEXT_CHARPOS* pCharPos, CFX_Font* pFont,
+ CFX_FontCache* pCache, const CFX_AffineMatrix* pObject2Device, FX_FLOAT font_size, FX_DWORD color,
+ int alpha_flag, void* pIccTransform);
+ virtual void* GetPlatformSurface()
+ {
+ return (void*)m_hDC;
+ }
+ HDC m_hDC;
+ FX_BOOL m_bCmykOutput;
+ int m_Width, m_Height, m_nBitsPerPixel;
+ int m_HorzSize, m_VertSize;
+ CPSOutput* m_pPSOutput;
+ CFX_PSRenderer m_PSRenderer;
+};
+void _Color2Argb(FX_ARGB& argb, FX_DWORD color, int alpha_flag, void* pIccTransform);