diff options
author | John Abd-El-Malek <jabdelmalek@google.com> | 2014-05-23 17:28:10 -0700 |
---|---|---|
committer | John Abd-El-Malek <jabdelmalek@google.com> | 2014-05-23 17:41:56 -0700 |
commit | 3f3b45cc74b0499912409f766a595945dbbfc4c5 (patch) | |
tree | ec400b6965477b88ea7f0d335f7e5c52044c346c /core/src/fxge | |
parent | 6fe4aed948337175f6f7f81bb03c37b9c7f535da (diff) | |
download | pdfium-3f3b45cc74b0499912409f766a595945dbbfc4c5.tar.xz |
Convert all line endings to LF.
Diffstat (limited to 'core/src/fxge')
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 ®ion);
- Region& operator=(const Region ®ion);
-protected:
-
-#else
- Region(const Region ®ion)
- {
- region; // reference parameter
- SetStatus(NotImplemented);
- }
-
- Region& operator=(const Region ®ion)
- {
- 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 ®ion); + Region& operator=(const Region ®ion); +protected: + +#else + Region(const Region ®ion) + { + region; // reference parameter + SetStatus(NotImplemented); + } + + Region& operator=(const Region ®ion) + { + 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(®ion);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN const RectF& rect)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionRect(&rect, ®ion);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN const Rect& rect)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionRectI(&rect, ®ion);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN const GraphicsPath* path)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionPath(path->nativePath, ®ion);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN const BYTE* regionData, IN INT size)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionRgnData(regionData, size, ®ion);
-
- SetNativeRegion(region);
-}
-
-inline
-Region::Region(IN HRGN hRgn)
-{
- GpRegion *region = NULL;
-
- lastResult = DllExports::GdipCreateRegionHrgn(hRgn, ®ion);
-
- SetNativeRegion(region);
-}
-
-inline
-Region* Region::FromHRGN(IN HRGN hRgn)
-{
- GpRegion *region = NULL;
-
- if (DllExports::GdipCreateRegionHrgn(hRgn, ®ion) == 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, ®ion));
-
- 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(®ion); + + SetNativeRegion(region); +} + +inline +Region::Region(IN const RectF& rect) +{ + GpRegion *region = NULL; + + lastResult = DllExports::GdipCreateRegionRect(&rect, ®ion); + + SetNativeRegion(region); +} + +inline +Region::Region(IN const Rect& rect) +{ + GpRegion *region = NULL; + + lastResult = DllExports::GdipCreateRegionRectI(&rect, ®ion); + + SetNativeRegion(region); +} + +inline +Region::Region(IN const GraphicsPath* path) +{ + GpRegion *region = NULL; + + lastResult = DllExports::GdipCreateRegionPath(path->nativePath, ®ion); + + SetNativeRegion(region); +} + +inline +Region::Region(IN const BYTE* regionData, IN INT size) +{ + GpRegion *region = NULL; + + lastResult = DllExports::GdipCreateRegionRgnData(regionData, size, ®ion); + + SetNativeRegion(region); +} + +inline +Region::Region(IN HRGN hRgn) +{ + GpRegion *region = NULL; + + lastResult = DllExports::GdipCreateRegionHrgn(hRgn, ®ion); + + SetNativeRegion(region); +} + +inline +Region* Region::FromHRGN(IN HRGN hRgn) +{ + GpRegion *region = NULL; + + if (DllExports::GdipCreateRegionHrgn(hRgn, ®ion) == 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, ®ion)); + + 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, ¶ms);
- 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, ¶ms);
- _Outline_CheckEmptyContour(¶ms);
- 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, ¶ms); + 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, ¶ms); + _Outline_CheckEmptyContour(¶ms); + 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*)¶m, sizeof(int), (char*)¶m) > 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*)¶m, sizeof(int), (char*)¶m) > 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*)¶m, sizeof(int), (char*)¶m) > 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*)¶m, sizeof(int), (char*)¶m) > 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); |